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