1use quote::quote;
2use syn::{Data, Fields, DataStruct, DeriveInput, parse_macro_input};
3use proc_macro::TokenStream;
4
5#[proc_macro_derive(SgxTypeDebug)]
6pub fn derive_sgx_type_debug(item: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(item as DeriveInput);
8 let struct_name = &input.ident;
9
10 let expanded = match input.data {
11 Data::Struct(DataStruct{ref fields,..}) => {
12 if let Fields::Named(ref fields_name) = fields {
13 let get_selfs: Vec<_> = fields_name.named.iter().map(|field| {
14 let field_name = field.ident.as_ref().unwrap();
15 match &field.ty {
16 syn::Type::Array(_) => quote! { add_debug_array_field(&mut s, stringify!(#field_name), &self.#field_name[..]); },
17 _ =>
18 quote! { add_debug_reg_field(&mut s, stringify!(#field_name), &self.#field_name); },
19 }
20 }).collect();
21
22 let implemented_debug = quote! {
23 impl core::fmt::Debug for #struct_name {
24 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
25 let mut s = f.debug_struct(stringify!(#struct_name));
26 unsafe { #(#get_selfs)* }
27 s.finish()
28 }
29 }
30 };
31 implemented_debug
32
33 } else {
34 panic!("SgxTypeDebug does not supports types other than Named Fields")
35 }
36 }
37 _ => panic!("SgxTypeDebug only support Struct")
38 };
39 expanded.into()
40}