ll_sparql_parser/
lib.rs

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