blob: 4703411afb453f9d9cc61f86c455c549973ef3a1 [file] [log] [blame]
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields};
#[proc_macro_derive(SgxTypeDebug)]
pub fn derive_sgx_type_debug(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as DeriveInput);
let struct_name = &input.ident;
let expanded = match input.data {
Data::Struct(DataStruct { ref fields, .. }) => match fields {
Fields::Named(ref fields_name) => {
let get_selfs: Vec<_> = fields_name.named.iter().map(|field| {
let field_name = field.ident.as_ref().unwrap();
match &field.ty {
syn::Type::Array(_) => quote! { add_debug_array_field(&mut s, stringify!(#field_name), &self.#field_name[..]); },
_ => quote! { add_debug_reg_field(&mut s, stringify!(#field_name), &self.#field_name); },
}
}).collect();
let implemented_debug = quote! {
impl core::fmt::Debug for #struct_name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let mut s = f.debug_struct(stringify!(#struct_name));
unsafe { #(#get_selfs)* }
s.finish()
}
}
};
implemented_debug
}
Fields::Unnamed(ref fields_unname) => {
let get_selfs: Vec<_> = fields_unname
.unnamed
.iter()
.enumerate()
.map(|(i, field)| match &field.ty {
syn::Type::Array(_) => {
let index = syn::Index::from(i);
quote! { add_debug_array_field(&mut s, stringify!(#index), &self.#index[..]); }
}
_ => {
let index = syn::Index::from(i);
quote! { add_debug_reg_field(&mut s, stringify!(#index), &self.#index) }
},
})
.collect();
let implemented_debug = quote! {
impl core::fmt::Debug for #struct_name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
let mut s = f.debug_struct(stringify!(#struct_name));
unsafe { #(#get_selfs)* }
s.finish()
}
}
};
implemented_debug
}
Fields::Unit => panic!("SgxTypeDebug does not supports types other than Named Fields"),
},
_ => panic!("SgxTypeDebug only support Struct"),
};
expanded.into()
}