rust_sitter/
__private.rs

1//! # DO NOT USE THIS MODULE!
2//!
3//! This module contains functions for use in the expanded macros produced by rust-sitter.
4//! They need to be public so they can be accessed at all (\*cough\* macro hygiene), but
5//! they are not intended to actually be called in any other circumstance.
6
7use 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<&LT::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}