1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
extern crate proc_macro;
#[macro_use]
extern crate syn;
#[macro_use]
extern crate quote;
use proc_macro::TokenStream;
use syn::DeriveInput;
#[doc(hidden)]
#[proc_macro_derive(TypeName)]
pub fn derive_topic_type(input: TokenStream) -> TokenStream {
let mut ast = parse_macro_input!(input as DeriveInput);
let name = &ast.ident;
let ty_params = ast
.generics
.type_params()
.map(|p| p.ident.clone())
.collect::<Vec<_>>();
{
let where_clause = ast.generics.make_where_clause();
for ty_name in &ty_params {
where_clause
.predicates
.push(parse_quote! { #ty_name: ::typename::TypeName });
}
}
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
let expanded = quote! {
impl #impl_generics ::typename::TypeName for #name #ty_generics #where_clause {
fn fmt(f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
let _ty_name = concat!(module_path!(), "::", stringify!(#name));
::typename::fmt::TypeFormatter::new(f, _ty_name)
#(
.type_param::< #ty_params >()
)*
.finish()
}
}
};
TokenStream::from(expanded)
}