1/// A stream of tokens
2#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
3pub struct TokenStream(pub String);
4
5impl From<String> for TokenStream {
6 fn from(tokens: String) -> Self {
7 Self(tokens)
8 }
9}
10
11impl From<&String> for TokenStream {
12 fn from(tokens: &String) -> Self {
13 Self(tokens.to_string())
14 }
15}
16
17impl From<&str> for TokenStream {
18 fn from(tokens: &str) -> Self {
19 Self(tokens.to_string())
20 }
21}
22
23impl 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
82impl Default for TokenStream {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl 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
100impl AsRef<TokenStream> for TokenStream {
101 fn as_ref(&self) -> &Self {
102 self
103 }
104}
105
106impl 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)]
114pub enum Delimiter {
115 /// `[]`
116 Bracket,
117 /// `{}`
118 Brace,
119 /// `()`
120 Parenthesis,
121}
122
123impl 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
144pub struct Literal {
145 inner: String,
146}
147
148macro_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
158impl 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
176impl 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