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}