1use crate::{tree_sitter, Extract};
8
9pub fn extract_struct_or_variant<T>(
10 node: tree_sitter::Node,
11 construct_expr: impl Fn(&mut Option<tree_sitter::TreeCursor>, &mut usize) -> T,
12) -> T {
13 let mut parent_cursor = node.walk();
14 construct_expr(
15 &mut if parent_cursor.goto_first_child() {
16 Some(parent_cursor)
17 } else {
18 None
19 },
20 &mut node.start_byte(),
21 )
22}
23
24pub fn extract_field<LT: Extract<T>, T>(
25 cursor_opt: &mut Option<tree_sitter::TreeCursor>,
26 source: &[u8],
27 last_idx: &mut usize,
28 field_name: &str,
29 closure_ref: Option<<::LeafFn>,
30) -> T {
31 if let Some(cursor) = cursor_opt.as_mut() {
32 loop {
33 let n = cursor.node();
34 if let Some(name) = cursor.field_name() {
35 if name == field_name {
36 let out = LT::extract(Some(n), source, *last_idx, closure_ref);
37
38 if !cursor.goto_next_sibling() {
39 *cursor_opt = None;
40 };
41
42 *last_idx = n.end_byte();
43
44 return out;
45 } else {
46 return LT::extract(None, source, *last_idx, closure_ref);
47 }
48 } else {
49 *last_idx = n.end_byte();
50 }
51
52 if !cursor.goto_next_sibling() {
53 return LT::extract(None, source, *last_idx, closure_ref);
54 }
55 }
56 } else {
57 LT::extract(None, source, *last_idx, closure_ref)
58 }
59}
60
61pub fn parse<T: Extract<T>>(
62 input: &str,
63 language: impl Fn() -> tree_sitter::Language,
64) -> core::result::Result<T, Vec<crate::errors::ParseError>> {
65 let mut parser = crate::tree_sitter::Parser::new();
66 parser.set_language(&language()).unwrap();
67 let tree = parser.parse(input, None).unwrap();
68 let root_node = tree.root_node();
69
70 if root_node.has_error() {
71 let mut errors = vec![];
72 crate::errors::collect_parsing_errors(&root_node, input.as_bytes(), &mut errors);
73
74 Err(errors)
75 } else {
76 Ok(<T as crate::Extract<_>>::extract(
77 Some(root_node),
78 input.as_bytes(),
79 0,
80 None,
81 ))
82 }
83}