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