1use std::collections::HashMap;
2
3use bevy_ecs::prelude::*;
4use lsp_core::prelude::*;
5use tracing::{info, instrument};
6
7use crate::{
8 lang::{
9 context::{Context, TokenIdx},
10 parser::parse_turtle,
11 tokenizer::parse_tokens_str,
12 },
13 TurtleLang,
14};
15
16#[instrument(skip(query, commands), name = "parse_source")]
17pub fn parse_source(
18 query: Query<(Entity, &Source), (Changed<Source>, With<TurtleLang>)>,
19 mut commands: Commands,
20) {
21 for (entity, source) in &query {
22 let (tok, es) = parse_tokens_str(source.0.as_str());
23 let t = Tokens(tok);
24 commands.entity(entity).insert(t);
25 commands.entity(entity).insert(Errors(es));
26 }
27}
28
29#[instrument(skip(query, commands, old), name = "parse_turtle")]
30pub fn parse_turtle_system(
31 query: Query<
32 (Entity, &Source, &Tokens, &Label, Option<&Open>),
33 (Changed<Tokens>, With<TurtleLang>),
34 >,
35 mut commands: Commands,
36 mut old: Local<HashMap<String, (Vec<Spanned<Token>>, Context)>>,
37 config: Res<ServerConfig>,
38) {
39 if !config.config.turtle.unwrap_or(true) {
40 return;
41 }
42 for (entity, source, tokens, label, open) in &query {
43 let (ref mut old_tokens, ref mut context) = old.entry(label.to_string()).or_default();
44 context.setup_current_to_prev(
45 TokenIdx { tokens: &tokens },
46 tokens.len(),
47 TokenIdx {
48 tokens: &old_tokens,
49 },
50 old_tokens.len(),
51 );
52 let empty = Context::new();
55 let (turtle, es) = parse_turtle(&label.0, tokens.0.clone(), source.0.len(), empty.ctx());
56 let (turtle, es) = es.is_empty().then_some((turtle, es)).unwrap_or_else(|| {
58 parse_turtle(&label.0, tokens.0.clone(), source.0.len(), context.ctx())
59 });
60
61 let es: Vec<_> = es.into_iter().map(|e| (e.map(|PToken(t, _)| t))).collect();
62
63 info!(
64 "{} triples ({} errors)",
65 turtle.value().triples.len(),
66 es.len()
67 );
68 if open.is_some() {
69 for e in &es {
70 info!("Error {:?}", e);
71 }
72 }
73
74 *old_tokens = tokens.0.clone();
75 context.clear();
76 turtle.set_context(context);
77
78 if es.is_empty() {
79 let element = Element::<TurtleLang>(turtle);
80 commands
81 .entity(entity)
82 .insert((element, Errors(es)))
83 .remove::<Dirty>();
84 } else {
85 let element = Element::<TurtleLang>(turtle);
86 commands.entity(entity).insert((Errors(es), element, Dirty));
87 }
88 }
89}
90
91pub fn derive_triples(
93 query: Query<(Entity, &Element<TurtleLang>), (Changed<Element<TurtleLang>>, With<TurtleLang>)>,
94 mut commands: Commands,
95) {
96 for (entity, turtle) in &query {
97 if let Ok(tripl) = turtle.0.get_simple_triples() {
98 let triples: Vec<_> = tripl.iter().map(|x| x.to_owned()).collect();
99 commands.entity(entity).insert(Triples(triples));
100 }
101 }
102}