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 {
new(span: Span, msg: &str) -> Self13     pub fn new(span: Span, msg: &str) -> Self {
14         Self::new2(span, span, msg)
15     }
16 
new2(begin: Span, end: Span, msg: &str) -> Self17     pub fn new2(begin: Span, end: Span, msg: &str) -> Self {
18         Error {
19             begin,
20             end,
21             msg: msg.to_owned(),
22         }
23     }
24 
to_compile_error(&self) -> TokenStream25     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