difftreelog
misc: Add docs on fields
in: master
1 file changed
crates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth223pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {3pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {4 let name = &ast.ident;4 let name = &ast.ident;5 let docs = ast5 let docs = extract_docs(&ast.attrs)?;6 .attrs7 .iter()8 .filter_map(|attr| {9 if let Some(ps) = attr.path.segments.first() {10 if ps.ident == "doc" {11 let meta = match attr.parse_meta() {12 Ok(meta) => meta,13 Err(e) => return Some(Err(e)),14 };15 match meta {16 syn::Meta::NameValue(mnv) => match &mnv.lit {17 syn::Lit::Str(ls) => return Some(Ok(ls.value())),18 _ => unreachable!(),19 },20 _ => unreachable!(),21 }22 }23 }24 None25 })26 .collect::<syn::Result<Vec<_>>>()?;27628 let (is_named_fields, field_names, field_types, params_count) = match &ast.data {7 let (is_named_fields, field_names, field_types, field_docs, params_count) = match &ast.data {29 syn::Data::Struct(ds) => match ds.fields {8 syn::Data::Struct(ds) => match ds.fields {30 syn::Fields::Named(ref fields) => Ok((9 syn::Fields::Named(ref fields) => Ok((31 true,10 true,32 fields.named.iter().enumerate().map(map_field_to_name),11 fields.named.iter().enumerate().map(map_field_to_name),33 fields.named.iter().map(map_field_to_type),12 fields.named.iter().map(map_field_to_type),13 fields.named.iter().map(map_field_to_doc),34 fields.named.len(),14 fields.named.len(),35 )),15 )),36 syn::Fields::Unnamed(ref fields) => Ok((16 syn::Fields::Unnamed(ref fields) => Ok((37 false,17 false,38 fields.unnamed.iter().enumerate().map(map_field_to_name),18 fields.unnamed.iter().enumerate().map(map_field_to_name),39 fields.unnamed.iter().map(map_field_to_type),19 fields.unnamed.iter().map(map_field_to_type),20 fields.unnamed.iter().map(map_field_to_doc),40 fields.unnamed.len(),21 fields.unnamed.len(),41 )),22 )),42 syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),23 syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),61 let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);42 let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);62 let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);43 let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);63 let solidity_struct_collect =44 let solidity_struct_collect =64 impl_solidity_struct_collect(name, field_names, field_types, &docs);45 impl_solidity_struct_collect(name, field_names, field_types, field_docs, &docs)?;654666 Ok(quote! {47 Ok(quote! {67 #can_be_plcaed_in_vec48 #can_be_plcaed_in_vec74 })55 })75}56}765777fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {58fn extract_docs(attrs: &Vec<syn::Attribute>) -> syn::Result<Vec<String>> {59 attrs60 .iter()78 quote! {61 .filter_map(|attr| {62 if let Some(ps) = attr.path.segments.first() {63 if ps.ident == "doc" {64 let meta = match attr.parse_meta() {65 Ok(meta) => meta,66 Err(e) => return Some(Err(e)),67 };68 match meta {79 impl ::evm_coder::sealed::CanBePlacedInVec for #ident {}69 syn::Meta::NameValue(mnv) => match &mnv.lit {70 syn::Lit::Str(ls) => return Some(Ok(ls.value())),71 _ => unreachable!(),72 },73 _ => unreachable!(),74 }75 }76 }77 None80 }78 })79 .collect()81}80}828183fn map_field_to_name(field: (usize, &syn::Field)) -> syn::Ident {82fn map_field_to_name(field: (usize, &syn::Field)) -> syn::Ident {95 &field.ty94 &field.ty96}95}9697fn map_field_to_doc(field: &syn::Field) -> Result<Vec<std::string::String>, syn::Error> {98 extract_docs(&field.attrs)99}100101fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {102 quote! {103 impl ::evm_coder::sealed::CanBePlacedInVec for #ident {}104 }105}9710698fn impl_abi_type<'a>(107fn impl_abi_type<'a>(99 name: &syn::Ident,108 name: &syn::Ident,283 name: &syn::Ident,292 name: &syn::Ident,284 field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,293 field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,285 field_types: impl Iterator<Item = &'a syn::Type> + Clone,294 field_types: impl Iterator<Item = &'a syn::Type> + Clone,295 field_docs: impl Iterator<Item = syn::Result<Vec<String>>> + Clone,286 docs: &Vec<String>,296 docs: &Vec<String>,287) -> proc_macro2::TokenStream {297) -> syn::Result<proc_macro2::TokenStream> {288 let string_name = name.to_string();298 let string_name = name.to_string();289 let name_type = field_names299 let name_type = field_names290 .into_iter()300 .into_iter()291 .zip(field_types.into_iter())301 .zip(field_types)302 .zip(field_docs)292 .map(|(name, ty)| {303 .map(|((name, ty), doc)| {304 let field_docs = match doc {305 Ok(doc) => doc.into_iter().enumerate().map(|(i, doc)| {306 let doc = doc.trim();307 let dev = if i == 0 { " @dev" } else { "" };308 quote! {309 writeln!(str, "///{} {}", #dev, #doc).unwrap();310 }311 }),312 Err(e) => unreachable!("{:?}", e),313 };293 let name = format!("{}", name);314 let name = format!("{}", name);294 quote!(315 quote!(316 #(#field_docs)*295 write!(str, "\t{} ", <#ty as ::evm_coder::solidity::StructCollect>::name()).unwrap();317 write!(str, "\t{} ", <#ty as ::evm_coder::solidity::StructCollect>::name()).unwrap();296 write!(str, "{};", #name).unwrap();318 writeln!(str, "{};", #name).unwrap();297 )319 )298 });320 });299 let docs = docs.iter().enumerate().map(|(i, doc)| {321 let docs = docs.iter().enumerate().map(|(i, doc)| {304 }326 }305 });327 });306328307 quote! {329 Ok(quote! {308 #[cfg(feature = "stubgen")]330 #[cfg(feature = "stubgen")]309 impl ::evm_coder::solidity::StructCollect for #name {331 impl ::evm_coder::solidity::StructCollect for #name {310 fn name() -> String {332 fn name() -> String {322 str344 str323 }345 }324 }346 }325 }347 })326}348}327349