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