blob: bf570851bbffa32efdeec59cd06156ffab373e30 [file] [log] [blame]
Alex Crichtoncbec8ec2017-06-02 13:19:33 -07001use std::ascii;
2use std::fmt;
3use std::iter;
4use std::ops;
5use std::str::FromStr;
6
7use proc_macro;
8
Alex Crichton1a7f7622017-07-05 17:47:15 -07009use {TokenTree, TokenNode, Delimiter, Spacing};
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070010
11#[derive(Clone)]
12pub struct TokenStream(proc_macro::TokenStream);
13
14pub struct LexError(proc_macro::LexError);
15
16impl TokenStream {
17 pub fn empty() -> TokenStream {
18 TokenStream(proc_macro::TokenStream::empty())
19 }
20
21 pub fn is_empty(&self) -> bool {
22 self.0.is_empty()
23 }
24}
25
26impl FromStr for TokenStream {
27 type Err = LexError;
28
29 fn from_str(src: &str) -> Result<TokenStream, LexError> {
30 Ok(TokenStream(src.parse().map_err(LexError)?))
31 }
32}
33
34impl fmt::Display for TokenStream {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 self.0.fmt(f)
37 }
38}
39
40impl From<proc_macro::TokenStream> for TokenStream {
41 fn from(inner: proc_macro::TokenStream) -> TokenStream {
42 TokenStream(inner)
43 }
44}
45
46impl From<TokenStream> for proc_macro::TokenStream {
47 fn from(inner: TokenStream) -> proc_macro::TokenStream {
48 inner.0
49 }
50}
51
52
53impl From<TokenTree> for TokenStream {
54 fn from(tree: TokenTree) -> TokenStream {
55 TokenStream(proc_macro::TokenTree {
56 span: (tree.span.0).0,
57 kind: match tree.kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -070058 TokenNode::Group(delim, s) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070059 let delim = match delim {
60 Delimiter::Parenthesis => proc_macro::Delimiter::Parenthesis,
61 Delimiter::Bracket => proc_macro::Delimiter::Bracket,
62 Delimiter::Brace => proc_macro::Delimiter::Brace,
63 Delimiter::None => proc_macro::Delimiter::None,
64 };
Alex Crichton1a7f7622017-07-05 17:47:15 -070065 proc_macro::TokenNode::Group(delim, (s.0).0)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070066 }
Alex Crichton1a7f7622017-07-05 17:47:15 -070067 TokenNode::Op(ch, kind) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070068 let kind = match kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -070069 Spacing::Joint => proc_macro::Spacing::Joint,
70 Spacing::Alone => proc_macro::Spacing::Alone,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070071 };
Alex Crichton1a7f7622017-07-05 17:47:15 -070072 proc_macro::TokenNode::Op(ch, kind)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070073 }
Alex Crichton1a7f7622017-07-05 17:47:15 -070074 TokenNode::Term(s) => {
75 proc_macro::TokenNode::Term((s.0).0)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070076 }
Alex Crichton1a7f7622017-07-05 17:47:15 -070077 TokenNode::Literal(l) => {
78 proc_macro::TokenNode::Literal((l.0).0)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -070079 }
80 },
81 }.into())
82 }
83}
84
85impl iter::FromIterator<TokenStream> for TokenStream {
86 fn from_iter<I: IntoIterator<Item=TokenStream>>(streams: I) -> Self {
87 let streams = streams.into_iter().map(|s| s.0);
88 TokenStream(streams.collect::<proc_macro::TokenStream>())
89 }
90}
91
92impl fmt::Debug for TokenStream {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 f.debug_struct("TokenStream")
95 .field("tts", &self.clone().into_iter().collect::<Vec<_>>())
96 .finish()
97 }
98}
99
100impl fmt::Debug for LexError {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 f.debug_struct("LexError").finish()
103 }
104}
105
Alex Crichton1a7f7622017-07-05 17:47:15 -0700106pub struct TokenTreeIter(proc_macro::TokenTreeIter);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700107
108impl IntoIterator for TokenStream {
109 type Item = TokenTree;
Alex Crichton1a7f7622017-07-05 17:47:15 -0700110 type IntoIter = TokenTreeIter;
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700111
Alex Crichton1a7f7622017-07-05 17:47:15 -0700112 fn into_iter(self) -> TokenTreeIter {
113 TokenTreeIter(self.0.into_iter())
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700114 }
115}
116
Alex Crichton1a7f7622017-07-05 17:47:15 -0700117impl Iterator for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700118 type Item = TokenTree;
119
120 fn next(&mut self) -> Option<TokenTree> {
121 let token = match self.0.next() {
122 Some(n) => n,
123 None => return None,
124 };
125 Some(TokenTree {
126 span: ::Span(Span(token.span)),
127 kind: match token.kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700128 proc_macro::TokenNode::Group(delim, s) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700129 let delim = match delim {
130 proc_macro::Delimiter::Parenthesis => Delimiter::Parenthesis,
131 proc_macro::Delimiter::Bracket => Delimiter::Bracket,
132 proc_macro::Delimiter::Brace => Delimiter::Brace,
133 proc_macro::Delimiter::None => Delimiter::None,
134 };
Alex Crichton1a7f7622017-07-05 17:47:15 -0700135 TokenNode::Group(delim, ::TokenStream(TokenStream(s)))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700136 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700137 proc_macro::TokenNode::Op(ch, kind) => {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700138 let kind = match kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700139 proc_macro::Spacing::Joint => Spacing::Joint,
140 proc_macro::Spacing::Alone => Spacing::Alone,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700141 };
Alex Crichton1a7f7622017-07-05 17:47:15 -0700142 TokenNode::Op(ch, kind)
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700143 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700144 proc_macro::TokenNode::Term(s) => {
145 TokenNode::Term(::Term(Term(s)))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700146 }
Alex Crichton1a7f7622017-07-05 17:47:15 -0700147 proc_macro::TokenNode::Literal(l) => {
148 TokenNode::Literal(::Literal(Literal(l)))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700149 }
150 },
151 })
152 }
153
154 fn size_hint(&self) -> (usize, Option<usize>) {
155 self.0.size_hint()
156 }
157}
158
Alex Crichton1a7f7622017-07-05 17:47:15 -0700159impl fmt::Debug for TokenTreeIter {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700160 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700161 f.debug_struct("TokenTreeIter").finish()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700162 }
163}
164
165#[derive(Copy, Clone, Default)]
166pub struct Span(proc_macro::Span);
167
168impl Span {
169 pub fn call_site() -> Span {
170 Span(proc_macro::Span::call_site())
171 }
172}
173
174impl fmt::Debug for Span {
175 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
176 f.debug_struct("Span")
177 .finish()
178 }
179}
180
181#[derive(Copy, Clone)]
Alex Crichton1a7f7622017-07-05 17:47:15 -0700182pub struct Term(proc_macro::Term);
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700183
Alex Crichton1a7f7622017-07-05 17:47:15 -0700184impl<'a> From<&'a str> for Term {
185 fn from(string: &'a str) -> Term {
186 Term(proc_macro::Term::intern(string))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700187 }
188}
189
Alex Crichton1a7f7622017-07-05 17:47:15 -0700190impl ops::Deref for Term {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700191 type Target = str;
192
193 fn deref(&self) -> &str {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700194 self.0.as_str()
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700195 }
196}
197
Alex Crichton1a7f7622017-07-05 17:47:15 -0700198impl fmt::Debug for Term {
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700199 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
200 (**self).fmt(f)
201 }
202}
203
204#[derive(Clone)]
205pub struct Literal(proc_macro::Literal);
206
207impl Literal {
208 pub fn byte_char(byte: u8) -> Literal {
209 match byte {
210 0 => Literal(to_literal("b'\\0'")),
211 b'\"' => Literal(to_literal("b'\"'")),
212 n => {
213 let mut escaped = "b'".to_string();
214 escaped.extend(ascii::escape_default(n).map(|c| c as char));
215 escaped.push('\'');
216 Literal(to_literal(&escaped))
217 }
218 }
219 }
220
221 pub fn byte_string(bytes: &[u8]) -> Literal {
222 let mut escaped = "b\"".to_string();
223 for b in bytes {
224 match *b {
225 b'\0' => escaped.push_str(r"\0"),
226 b'\t' => escaped.push_str(r"\t"),
227 b'\n' => escaped.push_str(r"\n"),
228 b'\r' => escaped.push_str(r"\r"),
229 b'"' => escaped.push_str("\\\""),
230 b'\\' => escaped.push_str("\\\\"),
231 b'\x20' ... b'\x7E' => escaped.push(*b as char),
232 _ => escaped.push_str(&format!("\\x{:02X}", b)),
233 }
234 }
235 escaped.push('"');
236 Literal(to_literal(&escaped))
237 }
238
239 pub fn doccomment(s: &str) -> Literal {
240 Literal(to_literal(s))
241 }
242
Alex Crichton1a7f7622017-07-05 17:47:15 -0700243 pub fn float(s: f64) -> Literal {
244 Literal(to_literal(&s.to_string()))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700245 }
246
Alex Crichton1a7f7622017-07-05 17:47:15 -0700247 pub fn integer(s: i64) -> Literal {
248 Literal(to_literal(&s.to_string()))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700249 }
250
251 pub fn raw_string(s: &str, pounds: usize) -> Literal {
252 let mut ret = format!("r");
253 ret.extend((0..pounds).map(|_| "#"));
254 ret.push('"');
255 ret.push_str(s);
256 ret.push('"');
257 ret.extend((0..pounds).map(|_| "#"));
258 Literal(to_literal(&ret))
259 }
260
261 pub fn raw_byte_string(s: &str, pounds: usize) -> Literal {
262 let mut ret = format!("br");
263 ret.extend((0..pounds).map(|_| "#"));
264 ret.push('"');
265 ret.push_str(s);
266 ret.push('"');
267 ret.extend((0..pounds).map(|_| "#"));
268 Literal(to_literal(&ret))
269 }
270}
271
272impl fmt::Display for Literal {
273 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274 self.0.fmt(f)
275 }
276}
277
278impl fmt::Debug for Literal {
279 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
280 fmt::Display::fmt(self, f)
281 }
282}
283
284fn to_literal(s: &str) -> proc_macro::Literal {
285 let stream = s.parse::<proc_macro::TokenStream>().unwrap();
286 match stream.into_iter().next().unwrap().kind {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700287 proc_macro::TokenNode::Literal(l) => l,
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700288 _ => unreachable!(),
289 }
290}
291
292macro_rules! ints {
293 ($($t:ty,)*) => {$(
294 impl From<$t> for Literal {
295 fn from(t: $t) -> Literal {
296 Literal(to_literal(&format!(concat!("{}", stringify!($t)), t)))
297 }
298 }
299 )*}
300}
301
302ints! {
303 u8, u16, u32, u64, usize,
304 i8, i16, i32, i64, isize,
305}
306
307macro_rules! floats {
308 ($($t:ident,)*) => {$(
309 impl From<$t> for Literal {
310 fn from(t: $t) -> Literal {
Alex Crichton1a7f7622017-07-05 17:47:15 -0700311 Literal(proc_macro::Literal::$t(t))
Alex Crichtoncbec8ec2017-06-02 13:19:33 -0700312 }
313 }
314 )*}
315}
316
317floats! {
318 f32, f64,
319}
320
321impl<'a> From<&'a str> for Literal {
322 fn from(t: &'a str) -> Literal {
323 Literal(proc_macro::Literal::string(t))
324 }
325}
326
327impl From<char> for Literal {
328 fn from(t: char) -> Literal {
329 Literal(proc_macro::Literal::character(t))
330 }
331}