windows_tokens/
token_stream.rs

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        iter.into_iter()
91            .fold(None, |accum: Option<TokenStream>, n| {
92                let mut ts = accum.unwrap_or_else(TokenStream::new);
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}