type_sitter_lib/query/
captures.rs1use crate::{raw, Query, UntypedNode};
2use std::fmt::Debug;
3use streaming_iterator::StreamingIterator;
4#[cfg(not(feature = "yak-sitter"))]
5use tree_sitter::Point;
6#[cfg(feature = "yak-sitter")]
7use yak_sitter::PointRange;
8
9#[cfg(feature = "yak-sitter")]
11pub struct QueryCaptures<'query, 'tree: 'query, Query: crate::Query> {
12 typed_query: &'query Query,
13 untyped_captures: raw::QueryCaptures<'query, 'tree>,
14}
15
16#[cfg(not(feature = "yak-sitter"))]
18pub struct QueryCaptures<
19 'query,
20 'tree: 'query,
21 Query: crate::Query,
22 Text: raw::TextProvider<I>,
23 I: AsRef<[u8]>,
24> {
25 typed_query: &'query Query,
26 untyped_captures: raw::QueryCaptures<'query, 'tree, Text, I>,
27}
28
29pub trait QueryCapture<'query, 'tree: 'query>: Debug + Clone {
31 type Query: Query<Capture<'query, 'tree> = Self>;
33
34 fn query(&self) -> &'query Self::Query;
36
37 #[cfg(feature = "yak-sitter")]
39 fn raw(&self) -> raw::QueryCapture<'query, 'tree>;
40
41 #[cfg(not(feature = "yak-sitter"))]
43 fn raw(&self) -> raw::QueryCapture<'tree>;
44
45 fn node(&self) -> &UntypedNode<'tree>;
47
48 fn node_mut(&mut self) -> &mut UntypedNode<'tree>;
50
51 fn name(&self) -> &'query str;
53
54 #[allow(clippy::unnecessary_cast)]
57 #[inline]
58 fn index(&self) -> usize {
59 self.raw().index as usize
60 }
61}
62
63#[cfg(feature = "yak-sitter")]
64impl<'query, 'tree: 'query, Query: crate::Query> QueryCaptures<'query, 'tree, Query> {
65 #[inline]
70 pub(super) unsafe fn new(
71 typed_query: &'query Query,
72 untyped_captures: raw::QueryCaptures<'query, 'tree>,
73 ) -> Self {
74 Self {
75 typed_query,
76 untyped_captures,
77 }
78 }
79
80 #[inline]
82 pub fn set_byte_range(&mut self, range: std::ops::Range<usize>) {
83 self.untyped_captures.set_byte_range(range)
84 }
85
86 #[inline]
88 pub fn set_point_range(&mut self, range: PointRange) {
89 self.untyped_captures.set_point_range(range)
90 }
91}
92
93#[cfg(not(feature = "yak-sitter"))]
94impl<'query, 'tree: 'query, Query: crate::Query, Text: raw::TextProvider<I>, I: AsRef<[u8]>>
95 QueryCaptures<'query, 'tree, Query, Text, I>
96{
97 #[inline]
102 pub(super) unsafe fn new(
103 typed_query: &'query Query,
104 untyped_captures: raw::QueryCaptures<'query, 'tree, Text, I>,
105 ) -> Self {
106 Self {
107 typed_query,
108 untyped_captures,
109 }
110 }
111
112 #[inline]
114 pub fn set_byte_range(&mut self, range: std::ops::Range<usize>) {
115 self.untyped_captures.set_byte_range(range)
116 }
117
118 #[inline]
120 pub fn set_point_range(&mut self, range: std::ops::Range<Point>) {
121 self.untyped_captures.set_point_range(range)
122 }
123}
124
125#[cfg(feature = "yak-sitter")]
126impl<'query, 'tree: 'query, Query: crate::Query> Iterator for QueryCaptures<'query, 'tree, Query> {
127 type Item = Query::Capture<'query, 'tree>;
128
129 #[inline]
131 fn next(&mut self) -> Option<Self::Item> {
132 let query = self.untyped_captures.query();
133 let tree = self.untyped_captures.tree();
134
135 unsafe {
137 self.untyped_captures
138 .as_inner_mut()
139 .next()
140 .map(|(m, index)| {
141 let inner_capture = m.captures[*index];
142 self.typed_query.wrap_capture(raw::QueryCapture {
143 node: raw::Node::new(inner_capture.node, tree),
144 index: inner_capture.index as usize,
145 name: query.capture_names()[inner_capture.index as usize],
146 })
147 })
148 }
149 }
150
151 #[inline]
152 fn size_hint(&self) -> (usize, Option<usize>) {
153 self.untyped_captures.size_hint()
154 }
155}
156
157#[cfg(not(feature = "yak-sitter"))]
158impl<'query, 'tree: 'query, Query: crate::Query, Text: raw::TextProvider<I>, I: AsRef<[u8]>>
159 Iterator for QueryCaptures<'query, 'tree, Query, Text, I>
160{
161 type Item = Query::Capture<'query, 'tree>;
162
163 #[inline]
164 fn next(&mut self) -> Option<Self::Item> {
165 unsafe {
167 self.untyped_captures
168 .next()
169 .map(|(m, index)| self.typed_query.wrap_capture(m.captures[*index]))
170 }
171 }
172
173 #[inline]
174 fn size_hint(&self) -> (usize, Option<usize>) {
175 self.untyped_captures.size_hint()
176 }
177}