1use std::iter::FromIterator;
2
3use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
4
5#[proc_macro_attribute]
6pub fn dtor(attribute: TokenStream, item: TokenStream) -> TokenStream {
7 generate("dtor", attribute, item)
8}
9
10fn generate(macro_type: &str, attribute: TokenStream, item: TokenStream) -> TokenStream {
17 let mut inner = TokenStream::new();
18
19 #[cfg(feature = "used_linker")]
20 inner.extend([
21 TokenTree::Punct(Punct::new('#', Spacing::Alone)),
22 TokenTree::Group(Group::new(Delimiter::Bracket, TokenStream::from_iter([
23 TokenTree::Ident(Ident::new("feature", Span::call_site())),
24 TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::from_iter([
25 TokenTree::Ident(Ident::new("used_linker", Span::call_site())),
26 ]))),
27 ]))),
28 ]);
29
30 #[cfg(feature = "__warn_on_missing_unsafe")]
31 inner.extend([
32 TokenTree::Punct(Punct::new('#', Spacing::Alone)),
33 TokenTree::Group(Group::new(Delimiter::Bracket, TokenStream::from_iter([
34 TokenTree::Ident(Ident::new("feature", Span::call_site())),
35 TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::from_iter([
36 TokenTree::Ident(Ident::new("__warn_on_missing_unsafe", Span::call_site())),
37 ]))),
38 ]))),
39 ]);
40
41 if attribute.is_empty() {
42 inner.extend([
44 TokenTree::Punct(Punct::new('#', Spacing::Alone)),
45 TokenTree::Group(Group::new(Delimiter::Bracket, TokenStream::from_iter([
46 TokenTree::Ident(Ident::new(macro_type, Span::call_site())),
47 ]))),
48 ]);
49 } else {
50 inner.extend([
51 TokenTree::Punct(Punct::new('#', Spacing::Alone)),
52 TokenTree::Group(Group::new(Delimiter::Bracket, TokenStream::from_iter([
53 TokenTree::Ident(Ident::new(macro_type, Span::call_site())),
54 TokenTree::Group(Group::new(Delimiter::Parenthesis, attribute)),
55 ]))),
56 ]);
57 }
58
59 inner.extend(item);
60
61 TokenStream::from_iter([
62 TokenTree::Punct(Punct::new(':', Spacing::Joint)),
63 TokenTree::Punct(Punct::new(':', Spacing::Alone)),
64 TokenTree::Ident(Ident::new(macro_type, Span::call_site())),
65 TokenTree::Punct(Punct::new(':', Spacing::Joint)),
66 TokenTree::Punct(Punct::new(':', Spacing::Alone)),
67 TokenTree::Ident(Ident::new("__support", Span::call_site())),
68 TokenTree::Punct(Punct::new(':', Spacing::Joint)),
69 TokenTree::Punct(Punct::new(':', Spacing::Alone)),
70 TokenTree::Ident(Ident::new(&format!("{}_parse", macro_type), Span::call_site())),
71 TokenTree::Punct(Punct::new('!', Spacing::Alone)),
72 TokenTree::Group(Group::new(Delimiter::Parenthesis, inner)),
73 TokenTree::Punct(Punct::new(';', Spacing::Alone)),
74 ])
75}