| 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 | |