aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_tt/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_tt/src/lib.rs')
-rw-r--r--crates/ra_tt/src/lib.rs131
1 files changed, 131 insertions, 0 deletions
diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs
new file mode 100644
index 000000000..d7c3c62bf
--- /dev/null
+++ b/crates/ra_tt/src/lib.rs
@@ -0,0 +1,131 @@
1macro_rules! impl_froms {
2 ($e:ident: $($v:ident), *) => {
3 $(
4 impl From<$v> for $e {
5 fn from(it: $v) -> $e {
6 $e::$v(it)
7 }
8 }
9 )*
10 }
11}
12
13use std::fmt;
14
15use smol_str::SmolStr;
16
17#[derive(Debug, Clone)]
18pub enum TokenTree {
19 Leaf(Leaf),
20 Subtree(Subtree),
21}
22impl_froms!(TokenTree: Leaf, Subtree);
23
24#[derive(Debug, Clone)]
25pub enum Leaf {
26 Literal(Literal),
27 Punct(Punct),
28 Ident(Ident),
29}
30impl_froms!(Leaf: Literal, Punct, Ident);
31
32#[derive(Debug, Clone)]
33pub struct Subtree {
34 pub delimiter: Delimiter,
35 pub token_trees: Vec<TokenTree>,
36}
37
38#[derive(Clone, Copy, Debug)]
39pub enum Delimiter {
40 Parenthesis,
41 Brace,
42 Bracket,
43 None,
44}
45
46#[derive(Debug, Clone)]
47pub struct Literal {
48 pub text: SmolStr,
49}
50
51#[derive(Debug, Clone, Copy, PartialEq, Eq)]
52pub struct Punct {
53 pub char: char,
54 pub spacing: Spacing,
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
58pub enum Spacing {
59 Alone,
60 Joint,
61}
62
63#[derive(Debug, Clone)]
64pub struct Ident {
65 pub text: SmolStr,
66}
67
68impl fmt::Display for TokenTree {
69 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70 match self {
71 TokenTree::Leaf(it) => fmt::Display::fmt(it, f),
72 TokenTree::Subtree(it) => fmt::Display::fmt(it, f),
73 }
74 }
75}
76
77impl fmt::Display for Subtree {
78 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
79 let (l, r) = match self.delimiter {
80 Delimiter::Parenthesis => ("(", ")"),
81 Delimiter::Brace => ("{", "}"),
82 Delimiter::Bracket => ("[", "]"),
83 Delimiter::None => ("", ""),
84 };
85 f.write_str(l)?;
86 let mut needs_space = false;
87 for tt in self.token_trees.iter() {
88 if needs_space {
89 f.write_str(" ")?;
90 }
91 needs_space = true;
92 match tt {
93 TokenTree::Leaf(Leaf::Punct(p)) => {
94 needs_space = p.spacing == Spacing::Alone;
95 fmt::Display::fmt(p, f)?
96 }
97 tt => fmt::Display::fmt(tt, f)?,
98 }
99 }
100 f.write_str(r)?;
101 Ok(())
102 }
103}
104
105impl fmt::Display for Leaf {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 match self {
108 Leaf::Ident(it) => fmt::Display::fmt(it, f),
109 Leaf::Literal(it) => fmt::Display::fmt(it, f),
110 Leaf::Punct(it) => fmt::Display::fmt(it, f),
111 }
112 }
113}
114
115impl fmt::Display for Ident {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 fmt::Display::fmt(&self.text, f)
118 }
119}
120
121impl fmt::Display for Literal {
122 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123 fmt::Display::fmt(&self.text, f)
124 }
125}
126
127impl fmt::Display for Punct {
128 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
129 fmt::Display::fmt(&self.char, f)
130 }
131}