1use quote::quote;
2use syn::Fields;
3use synstructure::{decl_derive, AddBounds};
4
5decl_derive!([Debug] => derive_debug);
6
7fn derive_debug(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
11 if s.variants().is_empty() {
13 return s.gen_impl(quote! {
14 gen impl debug3::Debug for @Self {
15 fn fmt(&self, f: &mut debug3::Formatter) {
16 match *self {}
17 }
18 }
19 });
20 }
21
22 s.add_bounds(AddBounds::Generics);
23
24 let variants = s.each_variant(|variant| {
25 let name = variant.ast().ident.to_string();
26
27 let debug_helper = match variant.ast().fields {
28 Fields::Named(_) | Fields::Unit => quote! {debug_struct},
29 Fields::Unnamed(_) => quote! {debug_tuple},
30 };
31
32 let variant_body = variant.bindings().iter().map(|b| {
33 let format = quote! {#b};
34
35 if let Some(ref name) = b.ast().ident.as_ref().map(<_>::to_string) {
36 quote! {
37 s.field(#name, #format);
38 }
39 } else {
40 quote! {
41 s.field(#format);
42 }
43 }
44 });
45
46 quote! {
47 let mut s = f.#debug_helper(#name);
48 #(#variant_body)*
49 s.finish()
50 }
51 });
52
53 s.gen_impl(quote! {
54 #[automatically_derived]
55 gen impl debug3::Debug for @Self {
56 fn fmt(&self, f: &mut debug3::Formatter) {
57 match self { #variants }
58 }
59 }
60 })
61}