Skip to main content

ll_sparql_parser/ast/
mod.rs

1mod utils;
2use crate::{syntax_kind::SyntaxKind, Sparql, SyntaxNode};
3use rowan::{cursor::SyntaxToken, SyntaxNodeChildren, TextRange, TextSize};
4use std::usize;
5use utils::nth_ancestor;
6
7#[derive(Debug, PartialEq)]
8pub struct QueryUnit {
9    syntax: SyntaxNode,
10}
11
12impl QueryUnit {
13    pub fn select_query(&self) -> Option<SelectQuery> {
14        SelectQuery::cast(
15            self.syntax
16                .first_child()?
17                .first_child_by_kind(&SelectQuery::can_cast)?,
18        )
19    }
20
21    pub fn prologue(&self) -> Option<Prologue> {
22        Prologue::cast(
23            self.syntax
24                .first_child()?
25                .first_child_by_kind(&Prologue::can_cast)?,
26        )
27    }
28}
29
30#[derive(Debug, PartialEq)]
31pub struct Prologue {
32    syntax: SyntaxNode,
33}
34
35impl Prologue {
36    pub fn prefix_declarations(&self) -> Vec<PrefixDeclaration> {
37        self.syntax
38            .children()
39            .filter_map(&PrefixDeclaration::cast)
40            .collect()
41    }
42}
43
44#[derive(Debug, PartialEq)]
45pub struct SolutionModifier {
46    syntax: SyntaxNode,
47}
48
49impl SolutionModifier {
50    pub fn group_clause(&self) -> Option<GroupClause> {
51        GroupClause::cast(self.syntax.first_child()?)
52    }
53
54    pub fn select_query(&self) -> Option<SelectQuery> {
55        self.syntax.parent().and_then(SelectQuery::cast)
56    }
57}
58
59#[derive(Debug, PartialEq)]
60pub struct GroupClause {
61    syntax: SyntaxNode,
62}
63
64#[derive(Debug, PartialEq)]
65pub struct PrefixDeclaration {
66    syntax: SyntaxNode,
67}
68
69impl PrefixDeclaration {
70    pub fn prefix(&self) -> Option<String> {
71        Some(
72            self.syntax
73                .first_child_or_token_by_kind(&|kind| kind == SyntaxKind::PNAME_NS)?
74                .to_string()
75                .split_once(":")
76                .expect("Every PNAME_NS should contain ':' at the end")
77                .0
78                .to_string(),
79        )
80    }
81
82    pub fn raw_uri_prefix(&self) -> Option<String> {
83        let s = self
84            .syntax
85            .first_child_or_token_by_kind(&|kind| kind == SyntaxKind::IRIREF)?
86            .to_string();
87        (s.len() >= 2).then_some(s[1..(s.len() - 1)].to_string())
88    }
89
90    pub fn uri_prefix(&self) -> Option<String> {
91        Some(
92            self.syntax
93                .first_child_or_token_by_kind(&|kind| kind == SyntaxKind::IRIREF)?
94                .to_string(),
95        )
96    }
97}
98
99#[derive(Debug, PartialEq)]
100pub struct SelectQuery {
101    syntax: SyntaxNode,
102}
103
104impl SelectQuery {
105    pub fn where_clause(&self) -> Option<WhereClause> {
106        WhereClause::cast(self.syntax.first_child_by_kind(&WhereClause::can_cast)?)
107    }
108    pub fn select_clause(&self) -> Option<SelectClause> {
109        SelectClause::cast(self.syntax.first_child_by_kind(&SelectClause::can_cast)?)
110    }
111    pub fn variables(&self) -> Vec<Var> {
112        if let Some(where_clause) = self.where_clause() {
113            if let Some(ggp) = where_clause.group_graph_pattern() {
114                return ggp
115                    .triple_blocks()
116                    .iter()
117                    .flat_map(|triple_block| {
118                        triple_block
119                            .triples()
120                            .iter()
121                            .flat_map(|triple| triple.visible_variables())
122                            .collect::<Vec<Var>>()
123                    })
124                    .collect();
125            }
126        }
127        vec![]
128    }
129
130    pub fn soulution_modifier(&self) -> Option<SolutionModifier> {
131        SolutionModifier::cast(self.syntax.last_child()?)
132    }
133}
134
135#[derive(Debug, PartialEq, Clone)]
136pub struct SelectClause {
137    syntax: SyntaxNode,
138}
139
140impl SelectClause {
141    /// All selected variables.
142    /// This excludes variables used in assignments
143    ///
144    /// **Example**
145    /// ```sparql
146    /// Select ?a (?b as ?c) {
147    ///     ...
148    /// }
149    /// ```
150    ///
151    /// here `variables` would return just **?a** and not **?b** or **?c**.
152    pub fn variables(&self) -> Vec<Var> {
153        self.syntax
154            .children()
155            .into_iter()
156            .filter_map(Var::cast)
157            .filter(|var| {
158                var.syntax()
159                    .prev_sibling()
160                    .is_none_or(|var| var.kind() != SyntaxKind::Expression)
161            })
162            .collect()
163    }
164
165    /// All selected variables plus all assigned variables.
166    /// This excludes variables used in assignments
167    ///
168    /// **Example**
169    /// ```sparql
170    /// Select ?a (?b as ?c) {
171    ///     ...
172    /// }
173    /// ```
174    /// result: [**?a**, **?c**]
175    pub fn projected_variables(&self) -> Vec<Var> {
176        self.syntax.children().filter_map(Var::cast).collect()
177    }
178
179    pub fn is_star_selection(&self) -> bool {
180        self.syntax()
181            .last_token()
182            .is_some_and(|last| last.kind() == SyntaxKind::Star)
183    }
184
185    /// All assignments in the select clause.
186    pub fn assignments(&self) -> Vec<Assignment> {
187        self.syntax
188            .children()
189            .filter_map(Var::cast)
190            .filter_map(|variable| {
191                variable
192                    .syntax()
193                    .prev_sibling()
194                    .and_then(Expression::cast)
195                    .map(|expression| Assignment {
196                        expression,
197                        variable,
198                    })
199            })
200            .collect()
201    }
202
203    pub fn select_query(&self) -> Option<SelectQuery> {
204        SelectQuery::cast(self.syntax.parent()?)
205    }
206}
207
208#[derive(Debug)]
209pub struct Assignment {
210    pub expression: Expression,
211    pub variable: Var,
212}
213
214#[derive(Debug)]
215pub struct Expression {
216    syntax: SyntaxNode,
217}
218
219impl Expression {
220    pub fn unaggregated_variables(&self) -> Vec<Var> {
221        let mut res = vec![];
222        let mut stack = vec![self.syntax.clone()];
223        while let Some(node) = stack.pop() {
224            if node.kind() != SyntaxKind::Aggregate {
225                stack.extend(node.children());
226            }
227            if let Some(var) = Var::cast(node) {
228                res.push(var);
229            }
230        }
231        res
232    }
233}
234
235#[derive(Debug)]
236pub enum GraphPatternNotTriples {
237    GroupOrUnionGraphPattern(GroupOrUnionGraphPattern),
238    OptionalGraphPattern(OptionalGraphPattern),
239    MinusGraphPattern(MinusGraphPattern),
240    GraphGraphPattern(GraphGraphPattern),
241    ServiceGraphPattern(ServiceGraphPattern),
242    Filter(Filter),
243    Bind(Bind),
244    InlineData(InlineData),
245}
246
247impl GraphPatternNotTriples {
248    pub fn group_graph_pattern(&self) -> Option<GraphGraphPattern> {
249        match self {
250            GraphPatternNotTriples::GroupOrUnionGraphPattern(_group_or_union_graph_pattern) => {
251                todo!()
252            }
253            GraphPatternNotTriples::OptionalGraphPattern(_optional_graph_pattern) => todo!(),
254            GraphPatternNotTriples::MinusGraphPattern(_minus_graph_pattern) => todo!(),
255            GraphPatternNotTriples::GraphGraphPattern(_graph_graph_pattern) => todo!(),
256            GraphPatternNotTriples::ServiceGraphPattern(_service_graph_pattern) => todo!(),
257            GraphPatternNotTriples::Filter(_filter) => None,
258            GraphPatternNotTriples::Bind(_bind) => None,
259            GraphPatternNotTriples::InlineData(_inline_data) => None,
260        }
261    }
262}
263
264#[derive(Debug)]
265pub struct GroupOrUnionGraphPattern {
266    syntax: SyntaxNode,
267}
268impl GroupOrUnionGraphPattern {
269    fn group_graph_patterns(&self) -> Vec<GroupGraphPattern> {
270        self.syntax
271            .children()
272            .filter_map(GroupGraphPattern::cast)
273            .collect()
274    }
275}
276
277#[derive(Debug)]
278pub struct OptionalGraphPattern {
279    syntax: SyntaxNode,
280}
281impl OptionalGraphPattern {
282    fn group_graph_pattern(&self) -> Option<GroupGraphPattern> {
283        self.syntax.last_child().and_then(GroupGraphPattern::cast)
284    }
285}
286
287#[derive(Debug)]
288pub struct MinusGraphPattern {
289    syntax: SyntaxNode,
290}
291impl MinusGraphPattern {
292    fn group_graph_pattern(&self) -> Option<GroupGraphPattern> {
293        self.syntax.last_child().and_then(GroupGraphPattern::cast)
294    }
295}
296
297#[derive(Debug)]
298pub struct GraphGraphPattern {
299    syntax: SyntaxNode,
300}
301impl GraphGraphPattern {
302    fn group_graph_pattern(&self) -> Option<GroupGraphPattern> {
303        self.syntax.last_child().and_then(GroupGraphPattern::cast)
304    }
305}
306
307#[derive(Debug)]
308pub struct Filter {
309    syntax: SyntaxNode,
310}
311
312#[derive(Debug)]
313pub struct Bind {
314    syntax: SyntaxNode,
315}
316
317#[derive(Debug, PartialEq, Clone)]
318pub struct InlineData {
319    syntax: SyntaxNode,
320}
321
322#[derive(Debug)]
323pub struct WhereClause {
324    syntax: SyntaxNode,
325}
326
327#[derive(Debug)]
328pub struct ServiceGraphPattern {
329    syntax: SyntaxNode,
330}
331
332impl ServiceGraphPattern {
333    pub fn iri(&self) -> Option<Iri> {
334        self.syntax
335            .children()
336            .find(|child| child.kind() == SyntaxKind::VarOrIri)
337            .and_then(|child| child.first_child().and_then(Iri::cast))
338    }
339
340    pub fn group_graph_pattern(&self) -> Option<GroupGraphPattern> {
341        self.syntax
342            .children()
343            .last()
344            .and_then(GroupGraphPattern::cast)
345    }
346}
347
348impl WhereClause {
349    pub fn group_graph_pattern(&self) -> Option<GroupGraphPattern> {
350        GroupGraphPattern::cast(self.syntax.first_child()?)
351    }
352
353    pub fn where_token(&self) -> Option<SyntaxToken> {
354        match self.syntax.first_child_or_token() {
355            Some(rowan::NodeOrToken::Token(token)) if token.kind() == SyntaxKind::WHERE => {
356                Some(token.into())
357            }
358            _ => None,
359        }
360    }
361}
362
363#[derive(Debug)]
364pub struct GroupGraphPattern {
365    syntax: SyntaxNode,
366}
367
368impl GroupGraphPattern {
369    pub fn triple_blocks(&self) -> Vec<TriplesBlock> {
370        self.syntax()
371            .first_child_by_kind(&|kind| kind == SyntaxKind::GroupGraphPatternSub)
372            .map(|ggp| ggp.children().filter_map(TriplesBlock::cast).collect())
373            .unwrap_or_default()
374    }
375
376    pub fn group_pattern_not_triples(&self) -> Vec<GraphPatternNotTriples> {
377        self.syntax()
378            .first_child_by_kind(&|kind| kind == SyntaxKind::GroupGraphPatternSub)
379            .map(|ggp| {
380                ggp.children()
381                    .filter_map(GraphPatternNotTriples::cast)
382                    .collect()
383            })
384            .unwrap_or_default()
385    }
386
387    pub fn r_paren_token(&self) -> Option<SyntaxToken> {
388        match self.syntax.last_child_or_token() {
389            Some(rowan::NodeOrToken::Token(token)) if token.kind() == SyntaxKind::RCurly => {
390                Some(token.into())
391            }
392            _ => None,
393        }
394    }
395
396    pub fn l_paren_token(&self) -> Option<SyntaxToken> {
397        match self.syntax.first_child_or_token() {
398            Some(rowan::NodeOrToken::Token(token)) if token.kind() == SyntaxKind::LCurly => {
399                Some(token.into())
400            }
401            _ => None,
402        }
403    }
404
405    pub fn sub_select(&self) -> Option<SelectQuery> {
406        self.syntax().first_child().and_then(SelectQuery::cast)
407    }
408}
409
410#[derive(Debug)]
411pub struct TriplesBlock {
412    syntax: SyntaxNode,
413}
414
415impl TriplesBlock {
416    /// Get the `Triple`'s contained in this `TriplesBlock`.
417    pub fn triples(&self) -> Vec<Triple> {
418        self.syntax
419            .children()
420            .filter_map(|child| match child.kind() {
421                SyntaxKind::TriplesSameSubjectPath => Some(vec![Triple::cast(child).unwrap()]),
422                SyntaxKind::TriplesBlock => Some(TriplesBlock::cast(child).unwrap().triples()),
423                _ => None,
424            })
425            .flatten()
426            .collect()
427    }
428
429    pub fn group_graph_pattern(&self) -> Option<GroupGraphPattern> {
430        GroupGraphPattern::cast(nth_ancestor(self.syntax.clone(), 2)?)
431    }
432
433    /// Get the Dot token that terminates the first triple in this block.
434    /// Grammar: TriplesBlock = TriplesSameSubjectPath ( '.' TriplesBlock? )?
435    pub fn trailing_dot(&self) -> Option<SyntaxToken> {
436        self.syntax
437            .children_with_tokens()
438            .find_map(|child| match child {
439                rowan::NodeOrToken::Token(token) if token.kind() == SyntaxKind::Dot => {
440                    Some(token.into())
441                }
442                _ => None,
443            })
444    }
445}
446
447#[derive(Debug, PartialEq)]
448pub struct Subject {
449    syntax: SyntaxNode,
450}
451
452#[derive(Debug, PartialEq, Clone)]
453pub struct Triple {
454    syntax: SyntaxNode,
455}
456
457impl Triple {
458    pub fn subject(&self) -> Option<Subject> {
459        self.syntax.first_child().and_then(Subject::cast)
460    }
461
462    pub fn properties_list_path(&self) -> Option<PropertyListPath> {
463        PropertyListPath::cast(self.syntax.children().nth(1)?)
464    }
465
466    /// Get the outer `TriplesBlock` this Triple is part of.
467    /// NOTE: TriplesBlock is defined recursivly
468    pub fn triples_block(&self) -> Option<TriplesBlock> {
469        let mut parent = self.syntax.parent()?;
470        if parent.kind() != SyntaxKind::TriplesBlock {
471            return None;
472        }
473        while let Some(node) = parent.parent() {
474            if node.kind() == SyntaxKind::TriplesBlock {
475                parent = node;
476            } else {
477                break;
478            }
479        }
480        Some(TriplesBlock::cast(parent).expect("parent should be a TriplesBlock"))
481    }
482}
483
484#[derive(Debug)]
485pub struct PropertyPath {
486    pub verb: Path,
487    pub object: ObjectList,
488}
489
490impl PropertyPath {
491    pub fn text(&self) -> String {
492        format!("{} {}", self.verb.text(), self.object.text())
493    }
494
495    pub fn text_range(&self) -> TextRange {
496        TextRange::new(
497            self.verb.syntax().text_range().start(),
498            self.object.syntax.text_range().end(),
499        )
500    }
501}
502
503#[derive(Debug)]
504pub struct Path {
505    syntax: SyntaxNode,
506}
507
508impl Path {
509    pub fn sub_paths(&self) -> SubPaths {
510        SubPaths {
511            children: self.syntax.children(),
512        }
513    }
514}
515
516pub struct SubPaths {
517    children: SyntaxNodeChildren<Sparql>,
518}
519
520impl Iterator for SubPaths {
521    type Item = Path;
522
523    fn next(&mut self) -> Option<Self::Item> {
524        while let Some(next_child) = self.children.next() {
525            if let Some(path) = Path::cast(next_child.into()) {
526                return Some(path);
527            }
528        }
529        None
530    }
531}
532
533#[derive(Debug)]
534pub struct ObjectList {
535    syntax: SyntaxNode,
536}
537
538#[derive(Debug, PartialEq, Clone)]
539pub struct BlankPropertyList {
540    syntax: SyntaxNode,
541}
542
543impl BlankPropertyList {
544    pub fn triple(&self) -> Option<Triple> {
545        match self.syntax.kind() {
546            SyntaxKind::BlankNodePropertyListPath => {
547                todo!()
548            }
549            SyntaxKind::BlankNodePropertyList => {
550                todo!()
551            }
552            SyntaxKind::BlankNode => self.syntax.ancestors().nth(7).and_then(Triple::cast),
553            _ => None,
554        }
555    }
556
557    pub fn is_object(&self) -> bool {
558        todo!()
559    }
560
561    pub fn is_subject(&self) -> bool {
562        todo!()
563    }
564
565    pub fn property_list(&self) -> Option<PropertyListPath> {
566        match self.syntax.kind() {
567            SyntaxKind::BlankNodePropertyListPath | SyntaxKind::BlankNodePropertyList => {
568                PropertyListPath::cast(self.syntax.first_child()?)
569            }
570
571            _ => None,
572        }
573    }
574}
575
576#[derive(Debug)]
577pub struct PropertyListPath {
578    syntax: SyntaxNode,
579}
580
581impl PropertyListPath {
582    pub fn properties(&self) -> Vec<PropertyPath> {
583        self.syntax
584            .children()
585            .step_by(2)
586            .filter_map(|child| {
587                match (
588                    Path::cast(child.clone()),
589                    child.next_sibling().and_then(ObjectList::cast),
590                ) {
591                    (None, None) | (None, Some(_)) | (Some(_), None) => None,
592                    (Some(path), Some(object_list)) => Some(PropertyPath {
593                        verb: path,
594                        object: object_list,
595                    }),
596                }
597            })
598            .collect()
599    }
600    pub fn variables(&self) -> Vec<Var> {
601        self.syntax
602            .children()
603            .filter_map(|child| match child.kind() {
604                SyntaxKind::VerbSimple => child.first_child().and_then(Var::cast),
605                _ => None,
606            })
607            .collect()
608    }
609}
610
611#[derive(Debug)]
612pub struct Iri {
613    syntax: SyntaxNode,
614}
615
616impl Iri {
617    pub fn prefixed_name(&self) -> Option<PrefixedName> {
618        self.syntax.first_child().and_then(PrefixedName::cast)
619    }
620
621    /// Converts a IRIREF "<abc>" into the raw string "abc"
622    /// Returns None this iri is a PrefixedName
623    pub fn raw_iri(&self) -> Option<String> {
624        (self.syntax.first_child_or_token()?.kind() == SyntaxKind::IRIREF
625            && self.syntax.text_range().len() >= 2.into())
626        .then(|| self.text()[1..usize::from(self.syntax.text_range().len()) - 1].to_string())
627    }
628
629    pub fn is_uncompressed(&self) -> bool {
630        self.syntax
631            .first_child_or_token()
632            .is_some_and(|child| child.kind() == SyntaxKind::IRIREF)
633    }
634}
635
636#[derive(Debug)]
637pub struct PrefixedName {
638    syntax: SyntaxNode,
639}
640
641impl PrefixedName {
642    pub fn prefix(&self) -> String {
643        self.syntax
644            .to_string()
645            .split_once(":")
646            .expect("Every PrefixedName should contain a ':'")
647            .0
648            .to_string()
649    }
650
651    pub fn name(&self) -> String {
652        self.syntax
653            .to_string()
654            .split_once(":")
655            .expect("Every PrefixedName should contain a ':'")
656            .1
657            .to_string()
658    }
659}
660
661#[derive(Debug)]
662pub struct VarOrTerm {
663    syntax: SyntaxNode,
664}
665
666impl VarOrTerm {
667    pub fn var(&self) -> Option<Var> {
668        Var::cast(self.syntax.first_child()?)
669    }
670
671    pub fn is_var(&self) -> bool {
672        self.syntax
673            .first_child()
674            .map_or(false, |child| child.kind() == SyntaxKind::Var)
675    }
676
677    pub fn is_term(&self) -> bool {
678        !self.is_var()
679    }
680}
681
682#[derive(Debug)]
683pub struct Var {
684    syntax: SyntaxNode,
685}
686
687impl Var {
688    pub fn triple(&self) -> Option<Triple> {
689        self.syntax.ancestors().find_map(Triple::cast)
690    }
691
692    /// Variable name without `?`
693    ///
694    /// ---
695    ///
696    /// `?subject` -> `subject`
697    pub fn var_name(&self) -> String {
698        self.syntax.text().to_string()[1..].to_string()
699    }
700}
701
702impl AstNode for Var {
703    #[inline]
704    fn kind() -> SyntaxKind {
705        SyntaxKind::Var
706    }
707
708    fn cast(syntax: SyntaxNode) -> Option<Self> {
709        if Self::can_cast(syntax.kind()) {
710            Some(Self { syntax })
711        } else {
712            None
713        }
714    }
715    #[inline]
716    fn syntax(&self) -> &SyntaxNode {
717        &self.syntax
718    }
719
720    fn visible_variables(&self) -> Vec<Var> {
721        vec![Var::cast(self.syntax().clone()).unwrap()]
722    }
723}
724
725impl AstNode for VarOrTerm {
726    #[inline]
727    fn kind() -> SyntaxKind {
728        SyntaxKind::VarOrTerm
729    }
730
731    fn cast(syntax: SyntaxNode) -> Option<Self> {
732        if Self::can_cast(syntax.kind()) {
733            Some(Self { syntax })
734        } else {
735            None
736        }
737    }
738    #[inline]
739    fn syntax(&self) -> &SyntaxNode {
740        &self.syntax
741    }
742
743    fn visible_variables(&self) -> Vec<Var> {
744        self.syntax
745            .first_child()
746            .and_then(Var::cast)
747            .map(|var| vec![var])
748            .unwrap_or_default()
749    }
750}
751
752impl AstNode for Iri {
753    #[inline]
754    fn kind() -> SyntaxKind {
755        SyntaxKind::iri
756    }
757
758    fn cast(syntax: SyntaxNode) -> Option<Self> {
759        if Self::can_cast(syntax.kind()) {
760            Some(Self { syntax })
761        } else {
762            None
763        }
764    }
765    #[inline]
766    fn syntax(&self) -> &SyntaxNode {
767        &self.syntax
768    }
769
770    fn visible_variables(&self) -> Vec<Var> {
771        vec![]
772    }
773}
774
775impl AstNode for PrefixedName {
776    #[inline]
777    fn kind() -> SyntaxKind {
778        SyntaxKind::PrefixedName
779    }
780
781    fn cast(syntax: SyntaxNode) -> Option<Self> {
782        if Self::can_cast(syntax.kind()) {
783            Some(Self { syntax })
784        } else {
785            None
786        }
787    }
788    #[inline]
789    fn syntax(&self) -> &SyntaxNode {
790        &self.syntax
791    }
792
793    fn visible_variables(&self) -> Vec<Var> {
794        vec![]
795    }
796}
797
798impl AstNode for Path {
799    fn kind() -> SyntaxKind {
800        SyntaxKind::VerbPath
801    }
802
803    fn can_cast(kind: SyntaxKind) -> bool {
804        matches!(
805            kind,
806            SyntaxKind::Path
807                | SyntaxKind::VerbPath
808                | SyntaxKind::VerbSimple
809                | SyntaxKind::PathAlternative
810                | SyntaxKind::PathSequence
811                | SyntaxKind::PathElt
812                | SyntaxKind::PathEltOrInverse
813                | SyntaxKind::PathPrimary
814                | SyntaxKind::PathNegatedPropertySet
815                | SyntaxKind::PathOneInPropertySet
816        )
817    }
818
819    fn cast(syntax: SyntaxNode) -> Option<Self> {
820        if Self::can_cast(syntax.kind()) {
821            Some(Self { syntax })
822        } else {
823            None
824        }
825    }
826
827    fn syntax(&self) -> &SyntaxNode {
828        &self.syntax
829    }
830
831    fn visible_variables(&self) -> Vec<Var> {
832        vec![]
833    }
834}
835
836impl AstNode for ObjectList {
837    fn kind() -> SyntaxKind {
838        SyntaxKind::ObjectListPath
839    }
840    fn can_cast(kind: SyntaxKind) -> bool {
841        matches!(kind, SyntaxKind::ObjectListPath | SyntaxKind::ObjectList)
842    }
843
844    fn cast(syntax: SyntaxNode) -> Option<Self> {
845        if Self::can_cast(syntax.kind()) {
846            Some(Self { syntax })
847        } else {
848            None
849        }
850    }
851
852    fn syntax(&self) -> &SyntaxNode {
853        &self.syntax
854    }
855
856    fn visible_variables(&self) -> Vec<Var> {
857        self.syntax.descendants().filter_map(Var::cast).collect()
858    }
859}
860
861impl AstNode for BlankPropertyList {
862    #[inline]
863    fn kind() -> SyntaxKind {
864        SyntaxKind::BlankNodePropertyListPath
865    }
866
867    fn can_cast(kind: SyntaxKind) -> bool {
868        matches!(
869            kind,
870            SyntaxKind::BlankNodePropertyListPath
871                | SyntaxKind::BlankNodePropertyList
872                | SyntaxKind::BlankNode
873        )
874    }
875
876    #[inline]
877    fn cast(syntax: SyntaxNode) -> Option<Self> {
878        if Self::can_cast(syntax.kind()) {
879            Some(Self { syntax })
880        } else {
881            None
882        }
883    }
884
885    #[inline]
886    fn syntax(&self) -> &SyntaxNode {
887        &self.syntax
888    }
889
890    fn visible_variables(&self) -> Vec<Var> {
891        self.syntax.descendants().filter_map(Var::cast).collect()
892    }
893}
894
895impl AstNode for PropertyListPath {
896    #[inline]
897    fn kind() -> SyntaxKind {
898        SyntaxKind::PropertyListPathNotEmpty
899    }
900
901    fn can_cast(kind: SyntaxKind) -> bool {
902        matches!(
903            kind,
904            SyntaxKind::PropertyListPath | SyntaxKind::PropertyListPathNotEmpty
905        )
906    }
907
908    #[inline]
909    fn cast(syntax: SyntaxNode) -> Option<Self> {
910        if Self::can_cast(syntax.kind()) {
911            Some(Self { syntax })
912        } else {
913            None
914        }
915    }
916
917    #[inline]
918    fn syntax(&self) -> &SyntaxNode {
919        &self.syntax
920    }
921
922    fn visible_variables(&self) -> Vec<Var> {
923        self.syntax.descendants().filter_map(Var::cast).collect()
924    }
925}
926
927impl AstNode for Subject {
928    #[inline]
929    fn kind() -> SyntaxKind {
930        SyntaxKind::VarOrTerm
931    }
932
933    fn can_cast(kind: SyntaxKind) -> bool {
934        matches!(kind, SyntaxKind::VarOrTerm | SyntaxKind::TriplesNodePath)
935    }
936
937    fn cast(syntax: SyntaxNode) -> Option<Self> {
938        if Self::can_cast(syntax.kind()) {
939            Some(Self { syntax })
940        } else {
941            None
942        }
943    }
944    #[inline]
945    fn syntax(&self) -> &SyntaxNode {
946        &self.syntax
947    }
948
949    fn visible_variables(&self) -> Vec<Var> {
950        self.syntax
951            .first_child()
952            .and_then(Var::cast)
953            .map(|var| vec![var])
954            .unwrap_or_default()
955    }
956}
957
958impl AstNode for Triple {
959    #[inline]
960    fn kind() -> SyntaxKind {
961        SyntaxKind::TriplesSameSubjectPath
962    }
963
964    fn cast(syntax: SyntaxNode) -> Option<Self> {
965        if Self::can_cast(syntax.kind()) {
966            Some(Self { syntax })
967        } else {
968            None
969        }
970    }
971    #[inline]
972    fn syntax(&self) -> &SyntaxNode {
973        &self.syntax
974    }
975
976    fn visible_variables(&self) -> Vec<Var> {
977        self.syntax.descendants().filter_map(Var::cast).collect()
978    }
979}
980
981impl AstNode for TriplesBlock {
982    #[inline]
983    fn kind() -> SyntaxKind {
984        SyntaxKind::TriplesBlock
985    }
986
987    fn cast(syntax: SyntaxNode) -> Option<Self> {
988        if Self::can_cast(syntax.kind()) {
989            Some(Self { syntax })
990        } else {
991            None
992        }
993    }
994
995    #[inline]
996    fn syntax(&self) -> &SyntaxNode {
997        &self.syntax
998    }
999
1000    fn visible_variables(&self) -> Vec<Var> {
1001        self.syntax.descendants().filter_map(Var::cast).collect()
1002    }
1003}
1004
1005impl AstNode for Expression {
1006    #[inline]
1007    fn kind() -> SyntaxKind {
1008        SyntaxKind::Expression
1009    }
1010
1011    fn cast(syntax: SyntaxNode) -> Option<Self> {
1012        if Self::can_cast(syntax.kind()) {
1013            Some(Self { syntax })
1014        } else {
1015            None
1016        }
1017    }
1018
1019    #[inline]
1020    fn syntax(&self) -> &SyntaxNode {
1021        &self.syntax
1022    }
1023
1024    fn visible_variables(&self) -> Vec<Var> {
1025        self.syntax.descendants().filter_map(Var::cast).collect()
1026    }
1027}
1028
1029impl AstNode for GroupGraphPattern {
1030    #[inline]
1031    fn kind() -> SyntaxKind {
1032        SyntaxKind::GroupGraphPattern
1033    }
1034
1035    fn cast(syntax: SyntaxNode) -> Option<Self> {
1036        if Self::can_cast(syntax.kind()) {
1037            Some(Self { syntax })
1038        } else {
1039            None
1040        }
1041    }
1042
1043    #[inline]
1044    fn syntax(&self) -> &SyntaxNode {
1045        &self.syntax
1046    }
1047
1048    fn visible_variables(&self) -> Vec<Var> {
1049        self.sub_select()
1050            .map(|select| select.visible_variables())
1051            .or(self.syntax.first_child().map(|child| {
1052                child
1053                    .children()
1054                    .into_iter()
1055                    .filter_map(|child| match child.kind() {
1056                        SyntaxKind::TriplesBlock => {
1057                            TriplesBlock::cast(child).map(|tp| tp.visible_variables())
1058                        }
1059                        SyntaxKind::GraphPatternNotTriples => GraphPatternNotTriples::cast(child)
1060                            .map(|pattern| pattern.visible_variables()),
1061                        _ => None,
1062                    })
1063                    .flatten()
1064                    .collect()
1065            }))
1066            .unwrap_or_default()
1067    }
1068}
1069
1070impl AstNode for WhereClause {
1071    #[inline]
1072    fn kind() -> SyntaxKind {
1073        SyntaxKind::WhereClause
1074    }
1075
1076    fn cast(syntax: SyntaxNode) -> Option<Self> {
1077        if Self::can_cast(syntax.kind()) {
1078            Some(Self { syntax })
1079        } else {
1080            None
1081        }
1082    }
1083
1084    #[inline]
1085    fn syntax(&self) -> &SyntaxNode {
1086        &self.syntax
1087    }
1088
1089    fn visible_variables(&self) -> Vec<Var> {
1090        self.group_graph_pattern()
1091            .map(|ggp| ggp.visible_variables())
1092            .unwrap_or_default()
1093    }
1094}
1095impl AstNode for OptionalGraphPattern {
1096    #[inline]
1097    fn kind() -> SyntaxKind {
1098        SyntaxKind::OptionalGraphPattern
1099    }
1100
1101    fn cast(syntax: SyntaxNode) -> Option<Self> {
1102        if Self::can_cast(syntax.kind()) {
1103            Some(Self { syntax })
1104        } else {
1105            None
1106        }
1107    }
1108
1109    #[inline]
1110    fn syntax(&self) -> &SyntaxNode {
1111        &self.syntax
1112    }
1113
1114    fn visible_variables(&self) -> Vec<Var> {
1115        self.group_graph_pattern()
1116            .map(|ggp| ggp.visible_variables())
1117            .unwrap_or_default()
1118    }
1119}
1120
1121impl AstNode for GroupOrUnionGraphPattern {
1122    #[inline]
1123    fn kind() -> SyntaxKind {
1124        SyntaxKind::GroupOrUnionGraphPattern
1125    }
1126
1127    fn cast(syntax: SyntaxNode) -> Option<Self> {
1128        if Self::can_cast(syntax.kind()) {
1129            Some(Self { syntax })
1130        } else {
1131            None
1132        }
1133    }
1134
1135    #[inline]
1136    fn syntax(&self) -> &SyntaxNode {
1137        &self.syntax
1138    }
1139
1140    fn visible_variables(&self) -> Vec<Var> {
1141        self.group_graph_patterns()
1142            .into_iter()
1143            .flat_map(|ggp| ggp.visible_variables())
1144            .collect()
1145    }
1146}
1147
1148impl AstNode for MinusGraphPattern {
1149    #[inline]
1150    fn kind() -> SyntaxKind {
1151        SyntaxKind::MinusGraphPattern
1152    }
1153
1154    fn cast(syntax: SyntaxNode) -> Option<Self> {
1155        if Self::can_cast(syntax.kind()) {
1156            Some(Self { syntax })
1157        } else {
1158            None
1159        }
1160    }
1161
1162    #[inline]
1163    fn syntax(&self) -> &SyntaxNode {
1164        &self.syntax
1165    }
1166
1167    fn visible_variables(&self) -> Vec<Var> {
1168        self.group_graph_pattern()
1169            .map(|ggp| ggp.visible_variables())
1170            .unwrap_or_default()
1171    }
1172}
1173
1174impl AstNode for GraphGraphPattern {
1175    #[inline]
1176    fn kind() -> SyntaxKind {
1177        SyntaxKind::GraphGraphPattern
1178    }
1179
1180    fn cast(syntax: SyntaxNode) -> Option<Self> {
1181        if Self::can_cast(syntax.kind()) {
1182            Some(Self { syntax })
1183        } else {
1184            None
1185        }
1186    }
1187
1188    #[inline]
1189    fn syntax(&self) -> &SyntaxNode {
1190        &self.syntax
1191    }
1192
1193    fn visible_variables(&self) -> Vec<Var> {
1194        self.group_graph_pattern()
1195            .map(|ggp| ggp.visible_variables())
1196            .unwrap_or_default()
1197    }
1198}
1199
1200impl AstNode for ServiceGraphPattern {
1201    #[inline]
1202    fn kind() -> SyntaxKind {
1203        SyntaxKind::ServiceGraphPattern
1204    }
1205
1206    fn cast(syntax: SyntaxNode) -> Option<Self> {
1207        if Self::can_cast(syntax.kind()) {
1208            Some(Self { syntax })
1209        } else {
1210            None
1211        }
1212    }
1213
1214    #[inline]
1215    fn syntax(&self) -> &SyntaxNode {
1216        &self.syntax
1217    }
1218
1219    fn visible_variables(&self) -> Vec<Var> {
1220        self.group_graph_pattern()
1221            .map(|ggp| ggp.visible_variables())
1222            .unwrap_or_default()
1223    }
1224}
1225
1226impl AstNode for Filter {
1227    #[inline]
1228    fn kind() -> SyntaxKind {
1229        SyntaxKind::Filter
1230    }
1231
1232    fn cast(syntax: SyntaxNode) -> Option<Self> {
1233        if Self::can_cast(syntax.kind()) {
1234            Some(Self { syntax })
1235        } else {
1236            None
1237        }
1238    }
1239
1240    #[inline]
1241    fn syntax(&self) -> &SyntaxNode {
1242        &self.syntax
1243    }
1244
1245    fn visible_variables(&self) -> Vec<Var> {
1246        self.syntax().descendants().filter_map(Var::cast).collect()
1247    }
1248}
1249
1250impl AstNode for Bind {
1251    #[inline]
1252    fn kind() -> SyntaxKind {
1253        SyntaxKind::Bind
1254    }
1255
1256    fn cast(syntax: SyntaxNode) -> Option<Self> {
1257        if Self::can_cast(syntax.kind()) {
1258            Some(Self { syntax })
1259        } else {
1260            None
1261        }
1262    }
1263
1264    #[inline]
1265    fn syntax(&self) -> &SyntaxNode {
1266        &self.syntax
1267    }
1268
1269    fn visible_variables(&self) -> Vec<Var> {
1270        self.syntax()
1271            .children()
1272            .last()
1273            .and_then(Var::cast)
1274            .map(|var| vec![var])
1275            .unwrap_or_default()
1276    }
1277}
1278
1279impl AstNode for InlineData {
1280    #[inline]
1281    fn kind() -> SyntaxKind {
1282        SyntaxKind::InlineData
1283    }
1284
1285    fn cast(syntax: SyntaxNode) -> Option<Self> {
1286        if Self::can_cast(syntax.kind()) {
1287            Some(Self { syntax })
1288        } else {
1289            None
1290        }
1291    }
1292
1293    #[inline]
1294    fn syntax(&self) -> &SyntaxNode {
1295        &self.syntax
1296    }
1297
1298    fn visible_variables(&self) -> Vec<Var> {
1299        self.syntax()
1300            .last_child()
1301            .and_then(|data_block| data_block.first_child())
1302            .and_then(|inline_data| match inline_data.kind() {
1303                SyntaxKind::InlineDataOneVar => inline_data
1304                    .first_child()
1305                    .and_then(Var::cast)
1306                    .map(|var| vec![var]),
1307                SyntaxKind::InlineDataFull => Some(
1308                    inline_data
1309                        .children_with_tokens()
1310                        .take_while(|child| child.kind() != SyntaxKind::RParen)
1311                        .filter_map(|child| child.into_node().and_then(Var::cast))
1312                        .collect(),
1313                ),
1314                _ => None,
1315            })
1316            .unwrap_or_default()
1317    }
1318}
1319
1320impl AstNode for SelectClause {
1321    #[inline]
1322    fn kind() -> SyntaxKind {
1323        SyntaxKind::SelectClause
1324    }
1325
1326    fn cast(syntax: SyntaxNode) -> Option<Self> {
1327        if Self::can_cast(syntax.kind()) {
1328            Some(Self { syntax })
1329        } else {
1330            None
1331        }
1332    }
1333
1334    #[inline]
1335    fn syntax(&self) -> &SyntaxNode {
1336        &self.syntax
1337    }
1338
1339    fn visible_variables(&self) -> Vec<Var> {
1340        self.projected_variables()
1341    }
1342}
1343
1344impl AstNode for Prologue {
1345    #[inline]
1346    fn kind() -> SyntaxKind {
1347        SyntaxKind::Prologue
1348    }
1349
1350    fn cast(syntax: SyntaxNode) -> Option<Self> {
1351        if Self::can_cast(syntax.kind()) {
1352            Some(Self { syntax })
1353        } else {
1354            None
1355        }
1356    }
1357
1358    #[inline]
1359    fn syntax(&self) -> &SyntaxNode {
1360        &self.syntax
1361    }
1362
1363    fn visible_variables(&self) -> Vec<Var> {
1364        vec![]
1365    }
1366}
1367
1368impl AstNode for SolutionModifier {
1369    #[inline]
1370    fn kind() -> SyntaxKind {
1371        SyntaxKind::SolutionModifier
1372    }
1373
1374    fn cast(syntax: SyntaxNode) -> Option<Self> {
1375        if Self::can_cast(syntax.kind()) {
1376            Some(Self { syntax })
1377        } else {
1378            None
1379        }
1380    }
1381
1382    #[inline]
1383    fn syntax(&self) -> &SyntaxNode {
1384        &self.syntax
1385    }
1386
1387    fn visible_variables(&self) -> Vec<Var> {
1388        vec![]
1389    }
1390}
1391
1392impl AstNode for GroupClause {
1393    #[inline]
1394    fn kind() -> SyntaxKind {
1395        SyntaxKind::GroupClause
1396    }
1397
1398    fn cast(syntax: SyntaxNode) -> Option<Self> {
1399        if Self::can_cast(syntax.kind()) {
1400            Some(Self { syntax })
1401        } else {
1402            None
1403        }
1404    }
1405
1406    #[inline]
1407    fn syntax(&self) -> &SyntaxNode {
1408        &self.syntax
1409    }
1410
1411    fn visible_variables(&self) -> Vec<Var> {
1412        self.syntax
1413            .children()
1414            .into_iter()
1415            .filter_map(|group_condition| group_condition.last_child())
1416            .filter_map(Var::cast)
1417            .collect()
1418    }
1419}
1420
1421impl AstNode for PrefixDeclaration {
1422    #[inline]
1423    fn kind() -> SyntaxKind {
1424        SyntaxKind::PrefixDecl
1425    }
1426
1427    fn cast(syntax: SyntaxNode) -> Option<Self> {
1428        if Self::can_cast(syntax.kind()) {
1429            Some(Self { syntax })
1430        } else {
1431            None
1432        }
1433    }
1434
1435    #[inline]
1436    fn syntax(&self) -> &SyntaxNode {
1437        &self.syntax
1438    }
1439
1440    fn visible_variables(&self) -> Vec<Var> {
1441        vec![]
1442    }
1443}
1444
1445impl AstNode for QueryUnit {
1446    #[inline]
1447    fn kind() -> SyntaxKind {
1448        SyntaxKind::QueryUnit
1449    }
1450
1451    fn cast(syntax: SyntaxNode) -> Option<Self> {
1452        if Self::can_cast(syntax.kind()) {
1453            Some(Self { syntax })
1454        } else {
1455            None
1456        }
1457    }
1458
1459    #[inline]
1460    fn syntax(&self) -> &SyntaxNode {
1461        &self.syntax
1462    }
1463
1464    fn visible_variables(&self) -> Vec<Var> {
1465        self.select_query()
1466            .map(|select_query| select_query.visible_variables())
1467            .unwrap_or_default()
1468    }
1469}
1470
1471impl AstNode for SelectQuery {
1472    #[inline]
1473    fn kind() -> SyntaxKind {
1474        SyntaxKind::SelectQuery
1475    }
1476
1477    fn can_cast(kind: SyntaxKind) -> bool {
1478        matches!(kind, SyntaxKind::SelectQuery | SyntaxKind::SubSelect)
1479    }
1480
1481    fn cast(syntax: SyntaxNode) -> Option<Self> {
1482        if Self::can_cast(syntax.kind()) {
1483            Some(Self { syntax })
1484        } else {
1485            None
1486        }
1487    }
1488
1489    #[inline]
1490    fn syntax(&self) -> &SyntaxNode {
1491        &self.syntax
1492    }
1493
1494    fn visible_variables(&self) -> Vec<Var> {
1495        if let Some(select_clause) = self.select_clause() {
1496            if let Some(SyntaxKind::Star) = select_clause
1497                .syntax
1498                .last_child_or_token()
1499                .map(|last| last.kind())
1500            {
1501                self.where_clause()
1502                    .map(|where_clause| where_clause.visible_variables())
1503                    .unwrap_or_default()
1504            } else {
1505                select_clause.visible_variables()
1506            }
1507        } else {
1508            Vec::new()
1509        }
1510    }
1511}
1512
1513impl AstNode for GraphPatternNotTriples {
1514    #[inline]
1515    fn kind() -> SyntaxKind {
1516        SyntaxKind::GraphPatternNotTriples
1517    }
1518
1519    fn can_cast(kind: SyntaxKind) -> bool {
1520        matches!(
1521            kind,
1522            SyntaxKind::GroupOrUnionGraphPattern
1523                | SyntaxKind::OptionalGraphPattern
1524                | SyntaxKind::MinusGraphPattern
1525                | SyntaxKind::GraphGraphPattern
1526                | SyntaxKind::ServiceGraphPattern
1527                | SyntaxKind::Filter
1528                | SyntaxKind::Bind
1529                | SyntaxKind::InlineData
1530        )
1531    }
1532
1533    fn cast(syntax: SyntaxNode) -> Option<Self> {
1534        let child = syntax.first_child()?;
1535        match child.kind() {
1536            SyntaxKind::GroupOrUnionGraphPattern => {
1537                Some(GraphPatternNotTriples::GroupOrUnionGraphPattern(
1538                    GroupOrUnionGraphPattern::cast(child)?,
1539                ))
1540            }
1541            SyntaxKind::OptionalGraphPattern => Some(GraphPatternNotTriples::OptionalGraphPattern(
1542                OptionalGraphPattern::cast(child)?,
1543            )),
1544            SyntaxKind::MinusGraphPattern => Some(GraphPatternNotTriples::MinusGraphPattern(
1545                MinusGraphPattern::cast(child)?,
1546            )),
1547            SyntaxKind::GraphGraphPattern => Some(GraphPatternNotTriples::GraphGraphPattern(
1548                GraphGraphPattern::cast(child)?,
1549            )),
1550            SyntaxKind::ServiceGraphPattern => Some(GraphPatternNotTriples::ServiceGraphPattern(
1551                ServiceGraphPattern::cast(child)?,
1552            )),
1553            SyntaxKind::Filter => Some(GraphPatternNotTriples::Filter(Filter::cast(child)?)),
1554            SyntaxKind::Bind => Some(GraphPatternNotTriples::Bind(Bind::cast(child)?)),
1555            SyntaxKind::InlineData => {
1556                Some(GraphPatternNotTriples::InlineData(InlineData::cast(child)?))
1557            }
1558            _ => None,
1559        }
1560    }
1561
1562    #[inline]
1563    fn syntax(&self) -> &SyntaxNode {
1564        match self {
1565            GraphPatternNotTriples::GroupOrUnionGraphPattern(x) => x.syntax(),
1566            GraphPatternNotTriples::OptionalGraphPattern(x) => x.syntax(),
1567            GraphPatternNotTriples::MinusGraphPattern(x) => x.syntax(),
1568            GraphPatternNotTriples::GraphGraphPattern(x) => x.syntax(),
1569            GraphPatternNotTriples::ServiceGraphPattern(x) => x.syntax(),
1570            GraphPatternNotTriples::Filter(x) => x.syntax(),
1571            GraphPatternNotTriples::Bind(x) => x.syntax(),
1572            GraphPatternNotTriples::InlineData(x) => x.syntax(),
1573        }
1574    }
1575
1576    fn visible_variables(&self) -> Vec<Var> {
1577        match self {
1578            GraphPatternNotTriples::GroupOrUnionGraphPattern(x) => x.visible_variables(),
1579            GraphPatternNotTriples::OptionalGraphPattern(x) => x.visible_variables(),
1580            GraphPatternNotTriples::MinusGraphPattern(x) => x.visible_variables(),
1581            GraphPatternNotTriples::GraphGraphPattern(x) => x.visible_variables(),
1582            GraphPatternNotTriples::ServiceGraphPattern(x) => x.visible_variables(),
1583            GraphPatternNotTriples::Filter(x) => x.visible_variables(),
1584            GraphPatternNotTriples::Bind(x) => x.visible_variables(),
1585            GraphPatternNotTriples::InlineData(x) => x.visible_variables(),
1586        }
1587    }
1588}
1589
1590pub trait AstNode {
1591    fn kind() -> SyntaxKind;
1592
1593    #[inline]
1594    fn can_cast(kind: SyntaxKind) -> bool {
1595        Self::kind() == kind
1596    }
1597
1598    fn cast(syntax: SyntaxNode) -> Option<Self>
1599    where
1600        Self: Sized;
1601
1602    fn syntax(&self) -> &SyntaxNode;
1603
1604    /// Returns all variables "visible" from outside the node.
1605    fn visible_variables(&self) -> Vec<Var>;
1606
1607    fn has_error(&self) -> bool {
1608        self.syntax()
1609            .preorder()
1610            .find(|walk_event| match walk_event {
1611                rowan::WalkEvent::Enter(node) if node.kind() == SyntaxKind::Error => true,
1612                _ => false,
1613            })
1614            .is_some()
1615    }
1616
1617    fn collect_decendants(&self, matcher: &impl Fn(SyntaxKind) -> bool) -> Vec<SyntaxNode> {
1618        self.syntax()
1619            .preorder()
1620            .filter_map(|walk_event| match walk_event {
1621                rowan::WalkEvent::Enter(node) if matcher(node.kind()) => Some(node),
1622                _ => None,
1623            })
1624            .collect()
1625    }
1626
1627    fn preorder_find_kind(&self, kind: SyntaxKind) -> Vec<SyntaxNode> {
1628        self.syntax()
1629            .preorder()
1630            .filter_map(|walk_event| match walk_event {
1631                rowan::WalkEvent::Enter(node) if node.kind() == kind => Some(node),
1632                _ => None,
1633            })
1634            .collect()
1635    }
1636
1637    fn used_prefixes(&self) -> Vec<String> {
1638        self.syntax()
1639            .descendants()
1640            .filter_map(PrefixedName::cast)
1641            .map(|prefixed_name| prefixed_name.prefix())
1642            .collect()
1643    }
1644
1645    fn text(&self) -> String {
1646        self.syntax().text().to_string()
1647    }
1648
1649    fn text_until(&self, offset: TextSize) -> String {
1650        let syntax = self.syntax();
1651        assert!(syntax.text_range().start() <= offset);
1652        syntax
1653            .text()
1654            .slice(TextSize::new(0)..(offset - syntax.text_range().start()))
1655            .to_string()
1656    }
1657}
1658
1659#[cfg(test)]
1660mod tests;