ll_sparql_parser/
lib.rs

1mod parser;
2pub mod syntax_kind;
3mod syntax_node;
4
5#[cfg(target_arch = "wasm32")]
6use js_sys::{Array, Object, Reflect};
7#[cfg(target_arch = "wasm32")]
8use rowan::TextSize;
9use syntax_kind::SyntaxKind;
10#[cfg(target_arch = "wasm32")]
11use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
12
13pub use syntax_node::*;
14
15pub fn parse_query(input: &str) -> SyntaxNode {
16    SyntaxNode::new_root(parser::parse_text(input, parser::TopEntryPoint::QueryUnit))
17}
18
19pub fn parse_update(input: &str) -> SyntaxNode {
20    SyntaxNode::new_root(parser::parse_text(input, parser::TopEntryPoint::UpdateUnit))
21}
22
23#[cfg(target_arch = "wasm32")]
24#[wasm_bindgen]
25pub fn get_parse_tree(input: &str, offset: u32) -> JsValue {
26    use parser::TopEntryPoint;
27
28    let root = SyntaxNode::new_root(parser::parse_text(input, TopEntryPoint::QueryUnit));
29    build_js_tree(&root, TextSize::new(offset))
30}
31
32#[cfg(target_arch = "wasm32")]
33fn build_js_tree(node: &SyntaxNode, offset: TextSize) -> JsValue {
34    let obj = Object::new();
35    Reflect::set(
36        &obj,
37        &JsValue::from_str("kind"),
38        &JsValue::from_str(&format!("{:?}", node.kind())),
39    )
40    .unwrap();
41    Reflect::set(&obj, &JsValue::from_str("type"), &JsValue::from_str("node")).unwrap();
42    Reflect::set(
43        &obj,
44        &JsValue::from_str("active"),
45        &JsValue::from_bool(node.text_range().contains(offset)),
46    )
47    .unwrap();
48
49    let children = Array::from_iter(node.children_with_tokens().filter_map(|child| match child {
50        rowan::NodeOrToken::Node(node) => Some(build_js_tree(&node, offset)),
51        rowan::NodeOrToken::Token(token) if token.kind() != SyntaxKind::WHITESPACE => {
52            let token_obj = Object::new();
53            Reflect::set(
54                &token_obj,
55                &JsValue::from_str("kind"),
56                &JsValue::from_str(&format!("{:?}", token.kind())),
57            )
58            .unwrap();
59            Reflect::set(
60                &token_obj,
61                &JsValue::from_str("type"),
62                &JsValue::from_str("token"),
63            )
64            .unwrap();
65            Reflect::set(
66                &token_obj,
67                &JsValue::from_str("text"),
68                &JsValue::from_str(token.text()),
69            )
70            .unwrap();
71            Reflect::set(
72                &token_obj,
73                &JsValue::from_str("active"),
74                &JsValue::from_bool(token.text_range().contains(offset)),
75            )
76            .unwrap();
77            Some(token_obj.into())
78        }
79        _ => None,
80    }));
81    Reflect::set(&obj, &JsValue::from_str("children"), &children.into()).unwrap();
82    obj.into()
83}