toml_parse/tkn_tree/
syntax.rs1use rowan::{GreenNode, GreenNodeBuilder};
2
3use super::err::TomlResult;
4use super::kinds::TomlKind::{self, *};
5use super::parse_tkns::Tokenizer;
6use super::walk::{walk, walk_tokens};
7
8pub type SyntaxNode = rowan::SyntaxNode<TomlLang>;
9pub type SyntaxToken = rowan::SyntaxToken<TomlLang>;
10pub type SyntaxElement = rowan::NodeOrToken<SyntaxNode, SyntaxToken>;
11
12pub trait SyntaxNodeExtTrait {
13 fn token_text(&self) -> String;
15 fn deep_eq(&self, other: &Self) -> bool;
20}
21
22impl From<TomlKind> for rowan::SyntaxKind {
23 fn from(kind: TomlKind) -> Self {
24 Self(kind as u16)
25 }
26}
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
29pub struct TomlLang;
30impl rowan::Language for TomlLang {
31 type Kind = TomlKind;
32 fn kind_from_raw(raw: rowan::SyntaxKind) -> Self::Kind {
33 assert!(raw.0 <= Root as u16);
34 unsafe { std::mem::transmute::<u16, TomlKind>(raw.0) }
35 }
36 fn kind_to_raw(kind: Self::Kind) -> rowan::SyntaxKind {
37 kind.into()
38 }
39}
40
41impl SyntaxNodeExtTrait for SyntaxNode {
42 fn token_text(&self) -> String {
43 walk_tokens(self).fold(String::default(), |mut s, tkn| {
44 s.push_str(tkn.text());
45 s
46 })
47 }
48
49 fn deep_eq(&self, other: &Self) -> bool {
50 for (a, b) in walk(self).zip(walk(other)) {
51 match (&a, &b) {
52 (SyntaxElement::Node(n1), SyntaxElement::Node(n2)) => {
53 if n1.token_text() != n2.token_text() {
54 return false;
55 }
56 }
57 (SyntaxElement::Token(t1), SyntaxElement::Token(t2)) => {
58 if t1.text() != t2.text() {
59 return false;
60 }
61 }
62 (_, _) => return false,
63 }
64 if a.kind() != b.kind() {
65 return false;
66 }
67 }
68 true
69 }
70}
71
72pub struct ParsedToml {
73 green: rowan::GreenNode,
74}
75
76impl ParsedToml {
77 pub fn syntax(&self) -> SyntaxNode {
78 SyntaxNode::new_root(self.green.clone())
79 }
80}
81
82pub struct Parser {
83 pub(crate) builder: GreenNodeBuilder<'static>,
85}
86
87impl Default for Parser {
88 fn default() -> Self {
89 Parser::new()
90 }
91}
92
93impl Parser {
94 pub fn new() -> Parser {
95 Self {
96 builder: GreenNodeBuilder::new(),
97 }
98 }
99 pub fn parse(self) -> TomlResult<ParsedToml> {
100 let green: GreenNode = self.builder.finish();
101 Ok(ParsedToml { green })
105 }
106}
107
108pub fn parse_it(input: &str) -> TomlResult<ParsedToml> {
127 let parse_builder = Parser::new();
128 let parsed = Tokenizer::parse(input, parse_builder)?;
129 parsed.parse()
130}