indoc/
error.rs

1use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5pub struct Error {
6    begin: Span,
7    end: Span,
8    msg: String,
9}
10
11impl 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}