type_sitter_lib/query/
matches.rs1use crate::query::match_captures::QueryMatchCaptures;
2use crate::{raw, Query};
3use std::fmt::Debug;
4use streaming_iterator::StreamingIterator;
5#[cfg(not(feature = "yak-sitter"))]
6use tree_sitter::Point;
7#[cfg(feature = "yak-sitter")]
8use yak_sitter::PointRange;
9
10#[cfg(feature = "yak-sitter")]
16pub struct QueryMatches<'query, 'tree: 'query, Query: crate::Query> {
17 typed_query: &'query Query,
18 untyped_matches: raw::QueryMatches<'query, 'tree>,
19 current_match: Option<*const Query::Match<'query, 'tree>>,
20}
21
22#[cfg(not(feature = "yak-sitter"))]
28pub struct QueryMatches<
29 'query,
30 'tree: 'query,
31 Query: crate::Query + 'tree,
32 Text: raw::TextProvider<I>,
33 I: AsRef<[u8]>,
34> {
35 typed_query: &'query Query,
36 untyped_matches: raw::QueryMatches<'query, 'tree, Text, I>,
37 current_match: Option<*const Query::Match<'query, 'tree>>,
38}
39
40pub trait QueryMatch<'query, 'tree: 'query>: Debug {
42 type Query: Query<Match<'query, 'tree> = Self>;
44
45 fn query(&self) -> &'query Self::Query;
47
48 #[cfg(feature = "yak-sitter")]
50 fn tree(&self) -> &'tree raw::Tree;
51
52 fn raw(&self) -> &raw::QueryMatch<'query, 'tree>;
54
55 fn into_raw(self) -> raw::QueryMatch<'query, 'tree>;
57
58 #[cfg(feature = "yak-sitter")]
60 #[inline]
61 fn captures(&self) -> QueryMatchCaptures<'query, 'tree, Self::Query> {
62 unsafe {
64 QueryMatchCaptures::new(self.query(), self.raw().as_inner().captures, self.tree())
65 }
66 }
67
68 #[cfg(not(feature = "yak-sitter"))]
70 #[inline]
71 fn captures(&self) -> QueryMatchCaptures<'query, 'tree, Self::Query> {
72 unsafe { QueryMatchCaptures::new(self.query(), self.raw().captures) }
74 }
75
76 #[inline]
80 fn remove(self)
81 where
82 Self: Sized,
83 'tree: 'query,
84 {
85 self.into_raw().remove()
86 }
87}
88
89#[cfg(feature = "yak-sitter")]
90impl<'query, 'tree: 'query, Query: crate::Query + 'tree> QueryMatches<'query, 'tree, Query> {
91 #[inline]
96 pub(super) unsafe fn from_raw(
97 typed_query: &'query Query,
98 untyped_matches: raw::QueryMatches<'query, 'tree>,
99 ) -> Self {
100 Self {
101 typed_query,
102 untyped_matches,
103 current_match: None,
104 }
105 }
106
107 #[inline]
109 pub fn set_byte_range(&mut self, range: std::ops::Range<usize>) {
110 self.untyped_matches.set_byte_range(range)
111 }
112
113 #[inline]
115 #[cfg(feature = "yak-sitter")]
116 pub fn set_point_range(&mut self, range: PointRange) {
117 self.untyped_matches.set_point_range(range)
118 }
119}
120
121#[cfg(not(feature = "yak-sitter"))]
122impl<
123 'query,
124 'tree: 'query,
125 Query: crate::Query + 'tree,
126 Text: raw::TextProvider<I>,
127 I: AsRef<[u8]>,
128 > QueryMatches<'query, 'tree, Query, Text, I>
129{
130 #[inline]
135 pub(super) unsafe fn from_raw(
136 typed_query: &'query Query,
137 untyped_matches: raw::QueryMatches<'query, 'tree, Text, I>,
138 ) -> Self {
139 Self {
140 typed_query,
141 untyped_matches,
142 current_match: None,
143 }
144 }
145
146 #[inline]
148 pub fn set_byte_range(&mut self, range: std::ops::Range<usize>) {
149 self.untyped_matches.set_byte_range(range)
150 }
151
152 #[inline]
154 pub fn set_point_range(&mut self, range: std::ops::Range<Point>) {
155 self.untyped_matches.set_point_range(range)
156 }
157}
158
159#[cfg(feature = "yak-sitter")]
161impl<'query, 'tree: 'query, Query: crate::Query + 'tree> StreamingIterator
162 for QueryMatches<'query, 'tree, Query>
163{
164 type Item = Query::Match<'query, 'tree>;
165
166 #[inline]
167 fn advance(&mut self) {
168 self.untyped_matches.advance();
169 self.current_match = unsafe {
171 self.untyped_matches
172 .get()
173 .map(|m| self.typed_query.wrap_match_ref(m) as *const _)
174 }
175 }
176
177 #[inline]
178 fn get(&self) -> Option<&Self::Item> {
179 self.current_match.map(|m| unsafe { &*m })
184 }
185
186 #[inline]
187 fn size_hint(&self) -> (usize, Option<usize>) {
188 self.untyped_matches.size_hint()
189 }
190}
191
192#[cfg(not(feature = "yak-sitter"))]
194impl<
195 'query,
196 'tree: 'query,
197 Query: crate::Query + 'tree,
198 Text: raw::TextProvider<I>,
199 I: AsRef<[u8]>,
200 > StreamingIterator for QueryMatches<'query, 'tree, Query, Text, I>
201{
202 type Item = Query::Match<'query, 'tree>;
203
204 #[inline]
205 fn advance(&mut self) {
206 self.untyped_matches.advance();
207 self.current_match = unsafe {
209 self.untyped_matches
210 .get()
211 .map(|m| self.typed_query.wrap_match_ref(m) as *const _)
212 }
213 }
214
215 #[inline]
216 fn get(&self) -> Option<&Self::Item> {
217 self.current_match.map(|m| unsafe { &*m })
222 }
223
224 #[inline]
225 fn size_hint(&self) -> (usize, Option<usize>) {
226 self.untyped_matches.size_hint()
227 }
228}