golang_parser/
lib.rs

1pub use tree_sitter;
2
3use tree_sitter::{Node, Tree};
4
5pub const NODE_KIND_COMMENT: &str = "comment";
6
7pub struct Parser {
8    code: String,
9    tree: Tree,
10}
11impl Parser {
12    pub fn new(code: impl AsRef<str>) -> Result<Self, Error> {
13        let mut parser = tree_sitter::Parser::new();
14        parser
15            .set_language(tree_sitter_go::language())
16            .map_err(|err| Error::TreeSitterLanguageError(err.to_string()))?;
17
18        let code = code.as_ref();
19        let code = if code.ends_with(';') {
20            code.to_owned()
21        } else {
22            format!("{};", code)
23        };
24
25        let tree = parser
26            .parse(&code, None)
27            .ok_or(Error::TreeSitterParseCodeFailed)?;
28
29        debug_assert!(tree.root_node().kind() == "source_file");
30
31        Ok(Self { code, tree })
32    }
33
34    pub fn get_source(&self) -> &[u8] {
35        &self.code.as_bytes()
36    }
37
38    pub fn get_root_node(&self) -> Node<'_> {
39        self.tree.root_node()
40    }
41}
42
43#[derive(thiserror::Error, Debug)]
44pub enum Error {
45    #[error("TreeSitterLanguageError {0}")]
46    TreeSitterLanguageError(String),
47    #[error("TreeSitterParseCodeFailed")]
48    TreeSitterParseCodeFailed,
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54
55    #[test]
56    fn simple() {
57        match Parser::new("var _ int") {
58            Ok(parser) => {
59                assert_eq!(parser.get_source(), b"var _ int;");
60                assert_eq!(
61                    parser.get_root_node().utf8_text(parser.get_source()),
62                    Ok("var _ int;")
63                );
64            }
65            Err(err) => assert!(false, "{:?}", err),
66        }
67
68        match Parser::new("var _ int;") {
69            Ok(parser) => {
70                assert_eq!(parser.get_source(), b"var _ int;");
71            }
72            Err(err) => assert!(false, "{:?}", err),
73        }
74    }
75}