use quote::{
quote,
quote_spanned,
};
use proc_macro2::TokenStream as TokenStream2;
use syn::spanned::Spanned as _;
use syn::Type;
pub(crate) fn generate_storage(_attr: TokenStream2, item: TokenStream2) -> TokenStream2 {
let contract_struct = syn::parse2::<syn::ItemStruct>(item).expect("generate storage error");
let span = contract_struct.span();
let ident = contract_struct.ident;
let fields = contract_struct.fields.iter();
let field_ident = contract_struct.fields
.iter()
.map(|f| f.ident.clone().unwrap())
.collect::<Vec<proc_macro2::Ident>>();
let field_ident_str = contract_struct.fields
.iter()
.map(|f| format!("{}", f.ident.clone().unwrap()))
.collect::<Vec<String>>();
let field_type = contract_struct.fields
.iter()
.map(|f| f.ty.clone())
.collect::<Vec<Type>>();
let prefix_token = if field_ident_str.len() > 0 {
quote! {prefix}
} else {
quote! {_prefix}
};
quote_spanned!( span=>
use fvm_std::spread::SpreadLayout;
pub struct #ident {
#( #fields ),*
}
impl SpreadLayout for #ident {
fn read_ledger(_key: &[u8], #prefix_token: &[u8]) -> Self {
#ident {
#(#field_ident: <#field_type>::read_ledger(#field_ident_str.as_bytes(), prefix),)*
}
}
fn write_ledger(&self, _key: &[u8], #prefix_token: &[u8]) {
#(SpreadLayout::write_ledger(&self.#field_ident, #field_ident_str.as_bytes(), prefix);)*
}
}
)
}