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(&mut self, other: &TokenStream) {
32 self.push_space();
33 self.0.push_str(&other.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 core::iter::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/// A delimiter around a block of code
101#[derive(Copy, Clone)]
102pub enum Delimiter {
103 /// `[]`
104 Bracket,
105 /// `{}`
106 Brace,
107 /// `()`
108 Parenthesis,
109}
110
111impl Delimiter {
112 /// The opening delimiter
113 pub fn open(self) -> char {
114 match self {
115 Delimiter::Bracket => '[',
116 Delimiter::Brace => '{',
117 Delimiter::Parenthesis => '(',
118 }
119 }
120
121 /// The closing delimiter
122 pub fn close(self) -> char {
123 match self {
124 Delimiter::Bracket => ']',
125 Delimiter::Brace => '}',
126 Delimiter::Parenthesis => ')',
127 }
128 }
129}
130
131/// A literal of some sort
132pub struct Literal {
133 inner: String,
134}
135
136macro_rules! unsuffixed {
137 ($ty:ty => $name:ident) => {
138 pub fn $name(n: $ty) -> Self {
139 Self { inner: n.to_string() }
140 }
141 };
142}
143
144impl Literal {
145 unsuffixed!(i64 => i64_unsuffixed);
146 unsuffixed!(usize => usize_unsuffixed);
147 unsuffixed!(u32 => u32_unsuffixed);
148 unsuffixed!(u16 => u16_unsuffixed);
149 unsuffixed!(u8 => u8_unsuffixed);
150
151 pub fn byte_string(s: &[u8]) -> Self {
152 Self { inner: format!("b\"{}\"", core::str::from_utf8(s).expect("Could not turn bytes into byte literal")) }
153 }
154
155 pub fn as_str(&self) -> &str {
156 &self.inner
157 }
158}
159
160impl core::fmt::Display for TokenStream {
161 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162 write!(f, "{}", self.as_str())
163 }
164}
165