Skip to main content

swls_lang_rdf_base/
parse.rs

1//! Shared, language-agnostic parse-phase systems for the text RDF syntaxes whose
2//! parsed model is the [`Turtle`](rdf_parsers::model::Turtle) model (Turtle / TriG / …).
3
4use bevy_ecs::prelude::*;
5use swls_core::prelude::*;
6
7use crate::traits::NamedNodeExt;
8
9/// Derive the [`Prefixes`] component (declared prefix → namespace map + base URL)
10/// from the parsed [`Element`] model.  The language marker `L` is used only to
11/// scope the query (`With<L>`), so Turtle, TriG and any other language whose
12/// element is the shared `Turtle` model reuse one implementation.
13pub fn derive_prefixes_system<L: Component>(
14    query: Query<(Entity, &Label, &Element), (Changed<Element>, With<L>)>,
15    mut commands: Commands,
16) {
17    for (entity, url, turtle) in &query {
18        let prefixes: Vec<_> = turtle
19            .prefixes
20            .iter()
21            .flat_map(|prefix| {
22                let url = prefix.value.value().expand(turtle.value())?;
23                let url = swls_core::lsp_types::Url::parse(&url).ok()?;
24                Some(Prefix {
25                    url,
26                    prefix: prefix.prefix.value().clone(),
27                })
28            })
29            .collect();
30
31        let base = turtle
32            .base
33            .as_ref()
34            .and_then(|b| {
35                b.0 .1
36                    .value()
37                    .expand(turtle.value())
38                    .and_then(|x| swls_core::lsp_types::Url::parse(&x).ok())
39            })
40            .unwrap_or(url.0.clone());
41
42        commands.entity(entity).insert(Prefixes(prefixes, base));
43    }
44}