1pub mod __private;
2
3use std::ops::Deref;
4
5pub use rust_sitter_macro::*;
6
7#[cfg(feature = "tree-sitter-standard")]
8pub use tree_sitter_runtime_standard as tree_sitter;
9
10#[cfg(feature = "tree-sitter-c2rust")]
11pub use tree_sitter_runtime_c2rust as tree_sitter;
12
13pub trait Extract<Output> {
16 type LeafFn: ?Sized;
17 fn extract(
18 node: Option<tree_sitter::Node>,
19 source: &[u8],
20 last_idx: usize,
21 leaf_fn: Option<&Self::LeafFn>,
22 ) -> Output;
23}
24
25pub struct WithLeaf<L> {
26 _phantom: std::marker::PhantomData<L>,
27}
28
29impl<L> Extract<L> for WithLeaf<L> {
30 type LeafFn = dyn Fn(&str) -> L;
31
32 fn extract(
33 node: Option<tree_sitter::Node>,
34 source: &[u8],
35 _last_idx: usize,
36 leaf_fn: Option<&Self::LeafFn>,
37 ) -> L {
38 node.and_then(|n| n.utf8_text(source).ok())
39 .map(|s| leaf_fn.unwrap()(s))
40 .unwrap()
41 }
42}
43
44impl Extract<()> for () {
45 type LeafFn = ();
46 fn extract(
47 _node: Option<tree_sitter::Node>,
48 _source: &[u8],
49 _last_idx: usize,
50 _leaf_fn: Option<&Self::LeafFn>,
51 ) {
52 }
53}
54
55impl<T: Extract<U>, U> Extract<Option<U>> for Option<T> {
56 type LeafFn = T::LeafFn;
57 fn extract(
58 node: Option<tree_sitter::Node>,
59 source: &[u8],
60 last_idx: usize,
61 leaf_fn: Option<&Self::LeafFn>,
62 ) -> Option<U> {
63 node.map(|n| T::extract(Some(n), source, last_idx, leaf_fn))
64 }
65}
66
67impl<T: Extract<U>, U> Extract<Box<U>> for Box<T> {
68 type LeafFn = T::LeafFn;
69 fn extract(
70 node: Option<tree_sitter::Node>,
71 source: &[u8],
72 last_idx: usize,
73 leaf_fn: Option<&Self::LeafFn>,
74 ) -> Box<U> {
75 Box::new(T::extract(node, source, last_idx, leaf_fn))
76 }
77}
78
79impl<T: Extract<U>, U> Extract<Vec<U>> for Vec<T> {
80 type LeafFn = T::LeafFn;
81 fn extract(
82 node: Option<tree_sitter::Node>,
83 source: &[u8],
84 mut last_idx: usize,
85 leaf_fn: Option<&Self::LeafFn>,
86 ) -> Vec<U> {
87 node.map(|node| {
88 let mut cursor = node.walk();
89 let mut out = vec![];
90 if cursor.goto_first_child() {
91 loop {
92 let n = cursor.node();
93 if cursor.field_name().is_some() {
94 out.push(T::extract(Some(n), source, last_idx, leaf_fn));
95 }
96
97 last_idx = n.end_byte();
98
99 if !cursor.goto_next_sibling() {
100 break;
101 }
102 }
103 }
104
105 out
106 })
107 .unwrap_or_default()
108 }
109}
110
111#[derive(Clone, Debug)]
112pub struct Spanned<T> {
114 pub value: T,
116 pub span: (usize, usize),
119}
120
121impl<T> Deref for Spanned<T> {
122 type Target = T;
123
124 fn deref(&self) -> &T {
125 &self.value
126 }
127}
128
129impl<T: Extract<U>, U> Extract<Spanned<U>> for Spanned<T> {
130 type LeafFn = T::LeafFn;
131 fn extract(
132 node: Option<tree_sitter::Node>,
133 source: &[u8],
134 last_idx: usize,
135 leaf_fn: Option<&Self::LeafFn>,
136 ) -> Spanned<U> {
137 Spanned {
138 value: T::extract(node, source, last_idx, leaf_fn),
139 span: node
140 .map(|n| (n.start_byte(), n.end_byte()))
141 .unwrap_or((last_idx, last_idx)),
142 }
143 }
144}
145
146pub mod errors {
147 #[cfg(feature = "tree-sitter-standard")]
148 use tree_sitter_runtime_standard as tree_sitter;
149
150 #[cfg(feature = "tree-sitter-c2rust")]
151 use tree_sitter_runtime_c2rust as tree_sitter;
152
153 #[derive(Debug)]
154 pub enum ParseErrorReason {
156 UnexpectedToken(String),
158 FailedNode(Vec<ParseError>),
161 MissingToken(String),
163 }
164
165 #[derive(Debug)]
166 pub struct ParseError {
168 pub reason: ParseErrorReason,
169 pub start: usize,
171 pub end: usize,
173 }
174
175 pub fn collect_parsing_errors(
178 node: &tree_sitter::Node,
179 source: &[u8],
180 errors: &mut Vec<ParseError>,
181 ) {
182 if node.is_error() {
183 if node.child(0).is_some() {
184 let mut inner_errors = vec![];
186 let mut cursor = node.walk();
187 node.children(&mut cursor)
188 .for_each(|c| collect_parsing_errors(&c, source, &mut inner_errors));
189
190 errors.push(ParseError {
191 reason: ParseErrorReason::FailedNode(inner_errors),
192 start: node.start_byte(),
193 end: node.end_byte(),
194 })
195 } else {
196 let contents = node.utf8_text(source).unwrap();
197 if !contents.is_empty() {
198 errors.push(ParseError {
199 reason: ParseErrorReason::UnexpectedToken(contents.to_string()),
200 start: node.start_byte(),
201 end: node.end_byte(),
202 })
203 } else {
204 errors.push(ParseError {
205 reason: ParseErrorReason::FailedNode(vec![]),
206 start: node.start_byte(),
207 end: node.end_byte(),
208 })
209 }
210 }
211 } else if node.is_missing() {
212 errors.push(ParseError {
213 reason: ParseErrorReason::MissingToken(node.kind().to_string()),
214 start: node.start_byte(),
215 end: node.end_byte(),
216 })
217 } else if node.has_error() {
218 let mut cursor = node.walk();
219 node.children(&mut cursor)
220 .for_each(|c| collect_parsing_errors(&c, source, errors));
221 }
222 }
223}