topiary_tree_sitter_facade/
query.rs

1#[cfg(not(target_arch = "wasm32"))]
2mod native {
3    use crate::{
4        error::QueryError, language::Language, node::Node, query_cursor::QueryCursor,
5        query_predicate::QueryPredicate,
6    };
7    use streaming_iterator::StreamingIterator;
8
9    pub struct Query {
10        pub(crate) inner: tree_sitter::Query,
11    }
12
13    impl Query {
14        #[inline]
15        pub fn new(language: &Language, source: &str) -> Result<Self, QueryError> {
16            let inner = tree_sitter::Query::new(&language.inner, source)?;
17            Ok(Self { inner })
18        }
19
20        #[inline]
21        pub fn matches<
22            'query,
23            'cursor: 'query,
24            'tree: 'query,
25            T: tree_sitter::TextProvider<I> + 'query,
26            I: AsRef<[u8]> + 'query,
27        >(
28            &'query self,
29            node: &Node<'tree>,
30            source: T,
31            cursor: &'cursor mut QueryCursor,
32        ) -> impl StreamingIterator<Item = tree_sitter::QueryMatch<'query, 'tree>> {
33            cursor.inner.matches(&self.inner, node.inner, source)
34        }
35
36        #[inline]
37        pub fn capture_names(&self) -> Vec<&str> {
38            self.inner.capture_names().to_vec()
39        }
40
41        #[inline]
42        pub fn general_predicates(&self, index: usize) -> Vec<QueryPredicate<'_>> {
43            self.inner
44                .general_predicates(index)
45                .iter()
46                .map(Into::into)
47                .collect()
48        }
49
50        #[inline]
51        pub fn pattern_count(&self) -> usize {
52            self.inner.pattern_count()
53        }
54
55        #[inline]
56        pub fn disable_pattern(&mut self, index: usize) {
57            self.inner.disable_pattern(index)
58        }
59
60        #[inline]
61        pub fn start_byte_for_pattern(&self, pattern_index: usize) -> usize {
62            self.inner.start_byte_for_pattern(pattern_index)
63        }
64
65        #[inline]
66        pub fn end_byte_for_pattern(&self, pattern_index: usize) -> usize {
67            self.inner.end_byte_for_pattern(pattern_index)
68        }
69    }
70
71    impl std::fmt::Debug for Query {
72        fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
73            std::fmt::Debug::fmt(&self.inner, fmt)
74        }
75    }
76
77    impl From<tree_sitter::Query> for Query {
78        #[inline]
79        fn from(inner: tree_sitter::Query) -> Self {
80            Self { inner }
81        }
82    }
83
84    impl std::panic::RefUnwindSafe for Query {}
85
86    unsafe impl Send for Query {}
87
88    unsafe impl Sync for Query {}
89
90    impl Unpin for Query {}
91
92    impl std::panic::UnwindSafe for Query {}
93}
94
95#[cfg(not(target_arch = "wasm32"))]
96pub use native::*;
97
98#[cfg(target_arch = "wasm32")]
99mod wasm {
100    use crate::{
101        error::QueryError, language::Language, node::Node, query_cursor::QueryCursor,
102        query_match::QueryMatch, query_predicate::QueryPredicate,
103    };
104    use wasm_bindgen::JsCast;
105
106    pub struct Query {
107        pub(crate) inner: topiary_web_tree_sitter_sys::Query,
108    }
109
110    impl Query {
111        #[inline]
112        pub fn new(language: &Language, source: &str) -> Result<Self, QueryError> {
113            let inner = language.inner.query(&source.into())?;
114            Ok(Self { inner })
115        }
116
117        #[inline]
118        pub fn matches<'a, 'tree: 'a>(
119            &'a self,
120            node: &Node<'tree>,
121            _source: &'a [u8],
122            _cursor: &'a mut QueryCursor,
123        ) -> impl ExactSizeIterator<Item = QueryMatch<'tree>> + 'tree {
124            self.inner
125                .matches(&node.inner, None, None)
126                .into_vec()
127                .into_iter()
128                .map(|value| {
129                    value
130                        .unchecked_into::<topiary_web_tree_sitter_sys::QueryMatch>()
131                        .into()
132                })
133        }
134
135        #[inline]
136        pub fn capture_names(&self) -> Vec<&str> {
137            // The Wasm code does not use this when looking up
138            // QueryCapture::name, the way the native code needs to.
139            vec![]
140        }
141
142        #[inline]
143        pub fn general_predicates(&self, index: usize) -> Vec<QueryPredicate> {
144            let predicates: Vec<_> = self
145                .inner
146                .predicates_for_pattern(index)
147                .into_vec()
148                .into_iter()
149                .map(|value| {
150                    value
151                        .unchecked_into::<topiary_web_tree_sitter_sys::QueryPredicate>()
152                        .into()
153                })
154                .collect();
155
156            predicates
157        }
158    }
159
160    impl std::fmt::Debug for Query {
161        fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
162            std::fmt::Debug::fmt(&self.inner, fmt)
163        }
164    }
165
166    impl Drop for Query {
167        #[inline]
168        fn drop(&mut self) {
169            self.inner.delete();
170        }
171    }
172
173    impl From<topiary_web_tree_sitter_sys::Query> for Query {
174        #[inline]
175        fn from(inner: topiary_web_tree_sitter_sys::Query) -> Self {
176            Self { inner }
177        }
178    }
179
180    impl std::panic::RefUnwindSafe for Query {}
181
182    unsafe impl Send for Query {}
183
184    unsafe impl Sync for Query {}
185
186    impl Unpin for Query {}
187
188    impl std::panic::UnwindSafe for Query {}
189}
190
191#[cfg(target_arch = "wasm32")]
192pub use wasm::*;