git.delta.rocks / unique-network / refs/commits / 9e324377d6bb

difftreelog

misc: Add docs on fields

Trubnikov Sergey2022-11-21parent: #12eee81.patch.diff
in: master

1 file changed

modifiedcrates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth
22
3pub(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 .attrs
7 .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 None
25 })
26 .collect::<syn::Result<Vec<_>>>()?;
276
28 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)?;
6546
66 Ok(quote! {47 Ok(quote! {
67 #can_be_plcaed_in_vec48 #can_be_plcaed_in_vec
74 })55 })
75}56}
7657
77fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {58fn extract_docs(attrs: &Vec<syn::Attribute>) -> syn::Result<Vec<String>> {
59 attrs
60 .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 None
80 }78 })
79 .collect()
81}80}
8281
83fn 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.ty
96}95}
96
97fn map_field_to_doc(field: &syn::Field) -> Result<Vec<std::string::String>, syn::Error> {
98 extract_docs(&field.attrs)
99}
100
101fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {
102 quote! {
103 impl ::evm_coder::sealed::CanBePlacedInVec for #ident {}
104 }
105}
97106
98fn 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_names
290 .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 });
306328
307 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 str
323 }345 }
324 }346 }
325 }347 })
326}348}
327349