Skip to main content

galvan_into_ast/
result.rs

1use thiserror::Error;
2
3use galvan_ast::Span;
4use galvan_parse::{Node, ParseError, TreeCursor};
5
6use crate::Ast;
7
8pub type AstResult = Result<Ast, AstError>;
9
10#[derive(Debug, Error)]
11pub enum AstError {
12    #[error("Error when converting parsed code to AST")]
13    ConversionError,
14    #[error("Error when parsing item")]
15    NodeError,
16    #[error("Duplicate main function")]
17    DuplicateMain,
18    #[error("Invalid character literal at {0:?}")]
19    InvalidCharacterLiteral(Span),
20    #[error(transparent)]
21    Parse(#[from] ParseError),
22}
23
24pub trait TreeSitterError: Sized {
25    fn err(self) -> Result<Self, AstError>;
26}
27
28impl TreeSitterError for Node<'_> {
29    fn err(self) -> Result<Self, AstError> {
30        if self.is_error() {
31            Err(AstError::NodeError)
32        } else {
33            Ok(self)
34        }
35    }
36}
37
38pub trait CursorUtil {
39    fn kind(&self) -> Result<&str, AstError>;
40    fn curr(&self) -> Result<Node<'_>, AstError>;
41    /// Goes to the next sibling, skipping comments if possible
42    fn next(&mut self) -> bool;
43    /// Goes to the first child, skipping comments if possible
44    fn child(&mut self) -> bool;
45}
46
47impl CursorUtil for TreeCursor<'_> {
48    fn kind(&self) -> Result<&str, AstError> {
49        Ok(self.curr()?.kind())
50    }
51
52    fn curr(&self) -> Result<Node<'_>, AstError> {
53        Ok(self.node().err()?)
54    }
55
56    fn next(&mut self) -> bool {
57        let mut res = self.goto_next_sibling();
58
59        while let Ok("comment") = self.kind() {
60            if !res { break; }
61            res = self.goto_next_sibling();
62        }
63
64        res
65    }
66
67    fn child(&mut self) -> bool {
68        let mut res = self.goto_first_child();
69
70        while let Ok("comment") = self.kind() {
71            if !res { break; }
72            res = self.goto_next_sibling();
73        }
74
75        res
76    }
77}