1#![forbid(unsafe_code)]
8
9use proc_macro::TokenStream;
10use quote::quote;
11
12#[proc_macro_derive(Hex)]
13pub fn derive_hex(item: TokenStream) -> TokenStream {
21 let input = syn::parse_macro_input!(item as syn::DeriveInput);
22 let ident = &input.ident;
23 let (impl_generics, ty_generics, where_clause) =
24 input.generics.split_for_impl();
25
26 (quote! {
27 impl #impl_generics ::core::fmt::LowerHex for #ident #ty_generics #where_clause {
28 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
29 if f.alternate() {
30 ::core::write!(f, "0x")?
31 }
32
33 for byte in self.to_bytes() {
34 ::core::write!(f, "{byte:02x}")?
35 }
36
37 ::core::result::Result::Ok(())
38 }
39 }
40
41 impl #impl_generics ::core::fmt::UpperHex for #ident #ty_generics #where_clause {
42 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
43 if f.alternate() {
44 ::core::write!(f, "0x")?
45 }
46
47 for byte in self.to_bytes() {
48 ::core::write!(f, "{byte:02X}")?
49 }
50
51 ::core::result::Result::Ok(())
52 }
53 }
54 })
55 .into()
56}
57
58#[proc_macro_derive(HexDebug)]
59pub fn derive_hex_debug(item: TokenStream) -> TokenStream {
68 let mut hex: TokenStream = derive_hex(item.clone());
69 let input = syn::parse_macro_input!(item as syn::DeriveInput);
70 let ident = &input.ident;
71 let (impl_generics, ty_generics, where_clause) =
72 input.generics.split_for_impl();
73
74 let dbg: TokenStream = (quote! {
75 impl #impl_generics ::core::fmt::Debug for #ident #ty_generics #where_clause {
76 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
77 const DEBUG_UPPER_HEX: u32 = 1 << 5;
81
82 #[allow(deprecated)]
83 if f.flags() & DEBUG_UPPER_HEX != 0 {
84 ::core::fmt::UpperHex::fmt(self, f)
85 } else { ::core::fmt::LowerHex::fmt(self, f)
87 }
88 }
89 }})
90 .into();
91
92 hex.extend(dbg);
93 hex
94}