1 | /// A stream of tokens |
2 | #[derive (Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] |
3 | pub struct TokenStream(pub String); |
4 | |
5 | impl From<String> for TokenStream { |
6 | fn from(tokens: String) -> Self { |
7 | Self(tokens) |
8 | } |
9 | } |
10 | |
11 | impl From<&String> for TokenStream { |
12 | fn from(tokens: &String) -> Self { |
13 | Self(tokens.to_string()) |
14 | } |
15 | } |
16 | |
17 | impl From<&str> for TokenStream { |
18 | fn from(tokens: &str) -> Self { |
19 | Self(tokens.to_string()) |
20 | } |
21 | } |
22 | |
23 | impl TokenStream { |
24 | pub fn new() -> Self { |
25 | Self(String::new()) |
26 | } |
27 | |
28 | /// Appends another stream to the stream |
29 | /// |
30 | /// note: a space will be inserted before the other stream |
31 | pub fn combine<T: AsRef<TokenStream>>(&mut self, other: T) { |
32 | self.push_space(); |
33 | self.0.push_str(&other.as_ref().0) |
34 | } |
35 | |
36 | #[must_use ] |
37 | pub fn join(&self, value: &str) -> Self { |
38 | Self(format!(" {}{value}" , self.0)) |
39 | } |
40 | |
41 | pub fn is_empty(&self) -> bool { |
42 | self.0.is_empty() |
43 | } |
44 | |
45 | /// View the stream as a string |
46 | pub fn as_str(&self) -> &str { |
47 | &self.0 |
48 | } |
49 | |
50 | /// Convert the stream into a `String` |
51 | pub fn into_string(self) -> String { |
52 | self.0 |
53 | } |
54 | |
55 | /// Parse the token stream as something |
56 | /// |
57 | /// Mostly used with `proc_macro2::TokenStream` or `proc_macro::TokenStream` |
58 | pub fn parse<T: core::str::FromStr>(self) -> Result<T, T::Err> { |
59 | self.into_string().parse() |
60 | } |
61 | |
62 | pub(crate) fn push_space(&mut self) { |
63 | match self.last_char() { |
64 | None | Some(' ' ) => {} |
65 | _ => self.0.push(' ' ), |
66 | } |
67 | } |
68 | |
69 | pub fn push(&mut self, c: char) { |
70 | self.0.push(c) |
71 | } |
72 | |
73 | pub fn push_str(&mut self, str: &str) { |
74 | self.0.push_str(str) |
75 | } |
76 | |
77 | fn last_char(&self) -> Option<char> { |
78 | self.0.chars().last() |
79 | } |
80 | } |
81 | |
82 | impl Default for TokenStream { |
83 | fn default() -> Self { |
84 | Self::new() |
85 | } |
86 | } |
87 | |
88 | impl FromIterator<TokenStream> for TokenStream { |
89 | fn from_iter<I: IntoIterator<Item = TokenStream>>(iter: I) -> Self { |
90 | iterOption.into_iter() |
91 | .fold(init:None, |accum: Option<TokenStream>, n: TokenStream| { |
92 | let mut ts: TokenStream = accum.unwrap_or_default(); |
93 | ts.combine(&n); |
94 | Some(ts) |
95 | }) |
96 | .unwrap_or_else(TokenStream::new) |
97 | } |
98 | } |
99 | |
100 | impl AsRef<TokenStream> for TokenStream { |
101 | fn as_ref(&self) -> &Self { |
102 | self |
103 | } |
104 | } |
105 | |
106 | impl AsRef<[u8]> for TokenStream { |
107 | fn as_ref(&self) -> &[u8] { |
108 | self.0.as_ref() |
109 | } |
110 | } |
111 | |
112 | /// A delimiter around a block of code |
113 | #[derive (Copy, Clone)] |
114 | pub enum Delimiter { |
115 | /// `[]` |
116 | Bracket, |
117 | /// `{}` |
118 | Brace, |
119 | /// `()` |
120 | Parenthesis, |
121 | } |
122 | |
123 | impl Delimiter { |
124 | /// The opening delimiter |
125 | pub fn open(self) -> char { |
126 | match self { |
127 | Delimiter::Bracket => '[' , |
128 | Delimiter::Brace => '{' , |
129 | Delimiter::Parenthesis => '(' , |
130 | } |
131 | } |
132 | |
133 | /// The closing delimiter |
134 | pub fn close(self) -> char { |
135 | match self { |
136 | Delimiter::Bracket => ']' , |
137 | Delimiter::Brace => '}' , |
138 | Delimiter::Parenthesis => ')' , |
139 | } |
140 | } |
141 | } |
142 | |
143 | /// A literal of some sort |
144 | pub struct Literal { |
145 | inner: String, |
146 | } |
147 | |
148 | macro_rules! unsuffixed { |
149 | ($ty:ty => $name:ident) => { |
150 | pub fn $name(n: $ty) -> Self { |
151 | Self { |
152 | inner: n.to_string(), |
153 | } |
154 | } |
155 | }; |
156 | } |
157 | |
158 | impl Literal { |
159 | unsuffixed!(i64 => i64_unsuffixed); |
160 | unsuffixed!(usize => usize_unsuffixed); |
161 | unsuffixed!(u32 => u32_unsuffixed); |
162 | unsuffixed!(u16 => u16_unsuffixed); |
163 | unsuffixed!(u8 => u8_unsuffixed); |
164 | |
165 | pub fn byte_string(s: &str) -> Self { |
166 | Self { |
167 | inner: format!("b \"{s}\"" ), |
168 | } |
169 | } |
170 | |
171 | pub fn as_str(&self) -> &str { |
172 | &self.inner |
173 | } |
174 | } |
175 | |
176 | impl core::fmt::Display for TokenStream { |
177 | fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { |
178 | write!(f, " {}" , self.as_str()) |
179 | } |
180 | } |
181 | |