1 | use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; |
2 | use std::iter::FromIterator; |
3 | |
4 | pub type Result<T> = std::result::Result<T, Error>; |
5 | |
6 | pub struct Error { |
7 | begin: Span, |
8 | end: Span, |
9 | msg: String, |
10 | } |
11 | |
12 | impl Error { |
13 | pub fn new(span: Span, msg: &str) -> Self { |
14 | Self::new2(span, span, msg) |
15 | } |
16 | |
17 | pub fn new2(begin: Span, end: Span, msg: &str) -> Self { |
18 | Error { |
19 | begin, |
20 | end, |
21 | msg: msg.to_owned(), |
22 | } |
23 | } |
24 | |
25 | pub fn to_compile_error(&self) -> TokenStream { |
26 | // compile_error! { $msg } |
27 | TokenStream::from_iter(vec![ |
28 | TokenTree::Ident(Ident::new("compile_error" , self.begin)), |
29 | TokenTree::Punct({ |
30 | let mut punct = Punct::new('!' , Spacing::Alone); |
31 | punct.set_span(self.begin); |
32 | punct |
33 | }), |
34 | TokenTree::Group({ |
35 | let mut group = Group::new(Delimiter::Brace, { |
36 | TokenStream::from_iter(vec![TokenTree::Literal({ |
37 | let mut string = Literal::string(&self.msg); |
38 | string.set_span(self.end); |
39 | string |
40 | })]) |
41 | }); |
42 | group.set_span(self.end); |
43 | group |
44 | }), |
45 | ]) |
46 | } |
47 | } |
48 | |