1use crate::error::ParserResult;
2use std::collections::HashMap;
3use tree_sitter::Node;
4
5pub struct ParseContext<'a> {
6 pub source: &'a [u8],
7 pub symbols: HashMap<String, String>,
8}
9
10impl<'a> ParseContext<'a> {
11 pub fn new(source: &'a [u8]) -> Self {
12 Self {
13 source,
14 symbols: HashMap::new(),
15 }
16 }
17
18 pub fn node_text(&self, node: &Node) -> ParserResult<&str> {
19 Ok(node.utf8_text(self.source)?)
20 }
21}
22
23pub trait FromTreeSitter<'a>: Sized {
24 fn from_node(node: Node<'a>, context: &mut ParseContext<'a>) -> ParserResult<Self>;
25}
26
27impl<'a> FromTreeSitter<'a> for String {
28 fn from_node(node: Node<'a>, context: &mut ParseContext<'a>) -> ParserResult<Self> {
29 Ok(context.node_text(&node)?.to_string())
30 }
31}
32
33impl<'a, T> FromTreeSitter<'a> for Box<T>
34where
35 T: FromTreeSitter<'a>,
36{
37 fn from_node(node: Node<'a>, context: &mut ParseContext<'a>) -> ParserResult<Self> {
38 Ok(Box::new(T::from_node(node, context)?))
39 }
40}
41
42pub fn parser_text(text: &str) -> ParserResult<crate::typed_ast::Specification> {
43 use crate::typed_ast::Specification;
44
45 let mut parser = tree_sitter::Parser::new();
46 parser.set_language(&tree_sitter_idl::language()).unwrap();
47
48 let tree = parser.parse(text, None).ok_or_else(|| {
49 crate::error::ParseError::TreeSitterError("Failed to parse text".to_string())
50 })?;
51
52 let root_node = tree.root_node();
53 if root_node.has_error() {
54 return Err(crate::error::ParseError::TreeSitterError(
55 "Failed to parse text".to_string(),
56 ));
57 }
58 let mut context = ParseContext::new(text.as_bytes());
59
60 Specification::from_node(root_node, &mut context)
61}