difftreelog
misk: Generate solidity docs for struct
in: master
4 files changed
crates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth--- a/crates/evm-coder/procedural/src/abi_derive.rs
+++ b/crates/evm-coder/procedural/src/abi_derive.rs
@@ -2,6 +2,29 @@
pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let name = &ast.ident;
+ let docs = ast
+ .attrs
+ .iter()
+ .filter_map(|attr| {
+ if let Some(ps) = attr.path.segments.first() {
+ if ps.ident == "doc" {
+ let meta = match attr.parse_meta() {
+ Ok(meta) => meta,
+ Err(e) => return Some(Err(e)),
+ };
+ match meta {
+ syn::Meta::NameValue(mnv) => match &mnv.lit {
+ syn::Lit::Str(ls) => return Some(Ok(ls.value())),
+ _ => unreachable!(),
+ },
+ _ => unreachable!(),
+ }
+ }
+ }
+ None
+ })
+ .collect::<syn::Result<Vec<_>>>()?;
+
let (is_named_fields, field_names, field_types, params_count) = match &ast.data {
syn::Data::Struct(ds) => match ds.fields {
syn::Fields::Named(ref fields) => Ok((
@@ -37,7 +60,8 @@
let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names.clone());
let solidity_type = impl_solidity_type(name, field_types.clone(), params_count);
let solidity_type_name = impl_solidity_type_name(name, field_types.clone(), params_count);
- let solidity_struct_collect = impl_solidity_struct_collect(name, field_names, field_types);
+ let solidity_struct_collect =
+ impl_solidity_struct_collect(name, field_names, field_types, &docs);
Ok(quote! {
#can_be_plcaed_in_vec
@@ -259,6 +283,7 @@
name: &syn::Ident,
field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,
field_types: impl Iterator<Item = &'a syn::Type> + Clone,
+ docs: &Vec<String>,
) -> proc_macro2::TokenStream {
let string_name = name.to_string();
let name_type = field_names
@@ -271,6 +296,13 @@
write!(str, "{};", #name).unwrap();
)
});
+ let docs = docs.iter().enumerate().map(|(i, doc)| {
+ let doc = doc.trim();
+ let dev = if i == 0 { " @dev" } else { "" };
+ quote! {
+ writeln!(str, "///{} {}", #dev, #doc).unwrap();
+ }
+ });
quote! {
#[cfg(feature = "stubgen")]
@@ -283,7 +315,7 @@
use std::fmt::Write;
let mut str = String::new();
- writeln!(str, "/// @dev Cross account struct").unwrap();
+ #(#docs)*
writeln!(str, "struct {} {{", Self::name()).unwrap();
#(#name_type)*
writeln!(str, "}}").unwrap();
crates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth1use super::{TypeCollector, SolidityTypeName, SolidityType, StructCollect};2use crate::{sealed, types::*};3use core::fmt;45macro_rules! solidity_type_name {6 ($($ty:ty => $name:literal $simple:literal = $default:literal),* $(,)?) => {7 $(8 impl SolidityTypeName for $ty {9 fn solidity_name(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {10 write!(writer, $name)11 }12 fn is_simple() -> bool {13 $simple14 }15 fn solidity_default(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {16 write!(writer, $default)17 }18 }1920 impl StructCollect for $ty {21 fn name() -> String {22 $name.to_string()23 }2425 fn declaration() -> String {26 String::default()27 }28 }29 )*30 };31}3233solidity_type_name! {34 uint8 => "uint8" true = "0",35 uint32 => "uint32" true = "0",36 uint64 => "uint64" true = "0",37 uint128 => "uint128" true = "0",38 uint256 => "uint256" true = "0",39 bytes4 => "bytes4" true = "bytes4(0)",40 address => "address" true = "0x0000000000000000000000000000000000000000",41 string => "string" false = "\"\"",42 bytes => "bytes" false = "hex\"\"",43 bool => "bool" true = "false",44}4546impl SolidityTypeName for void {47 fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {48 Ok(())49 }50 fn is_simple() -> bool {51 true52 }53 fn solidity_default(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {54 Ok(())55 }56 fn is_void() -> bool {57 true58 }59}6061impl<T: SolidityTypeName + sealed::CanBePlacedInVec> SolidityTypeName for Vec<T> {62 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {63 T::solidity_name(writer, tc)?;64 write!(writer, "[]")65 }66 fn is_simple() -> bool {67 false68 }69 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {70 write!(writer, "new ")?;71 T::solidity_name(writer, tc)?;72 write!(writer, "[](0)")73 }74}7576macro_rules! count {77 () => (0usize);78 ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));79}8081macro_rules! impl_tuples {82 ($($ident:ident)+) => {83 impl<$($ident: SolidityTypeName + 'static),+> SolidityType for ($($ident,)+) {84 fn names(tc: &TypeCollector) -> Vec<string> {85 let mut collected = Vec::with_capacity(Self::len());86 $({87 let mut out = string::new();88 $ident::solidity_name(&mut out, tc).expect("no fmt error");89 collected.push(out);90 })*;91 collected92 }9394 fn len() -> usize {95 count!($($ident)*)96 }97 }98 impl<$($ident: SolidityTypeName + 'static),+> SolidityTypeName for ($($ident,)+) {99 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {100 write!(writer, "{}", tc.collect_tuple::<Self>())101 }102 fn is_simple() -> bool {103 false104 }105 #[allow(unused_assignments)]106 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {107 write!(writer, "{}(", tc.collect_tuple::<Self>())?;108 let mut first = true;109 $(110 if !first {111 write!(writer, ",")?;112 } else {113 first = false;114 }115 <$ident>::solidity_default(writer, tc)?;116 )*117 write!(writer, ")")118 }119 }120 };121}122123impl_tuples! {A}124impl_tuples! {A B}125impl_tuples! {A B C}126impl_tuples! {A B C D}127impl_tuples! {A B C D E}128impl_tuples! {A B C D E F}129impl_tuples! {A B C D E F G}130impl_tuples! {A B C D E F G H}131impl_tuples! {A B C D E F G H I}132impl_tuples! {A B C D E F G H I J}133134impl sealed::CanBePlacedInVec for Property {}135impl StructCollect for Property {136 fn name() -> String {137 "Property".into()138 }139140 fn declaration() -> String {141 let mut str = String::new();142 writeln!(str, "/// @dev Property struct").unwrap();143 writeln!(str, "struct {} {{", Self::name()).unwrap();144 writeln!(str, "\tstring key;").unwrap();145 writeln!(str, "\tbytes value;").unwrap();146 writeln!(str, "}}").unwrap();147 str148 }149}150151impl SolidityTypeName for Property {152 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {153 write!(writer, "{}", tc.collect_struct::<Self>())154 }155156 fn is_simple() -> bool {157 false158 }159160 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {161 write!(writer, "{}(", tc.collect_struct::<Self>())?;162 address::solidity_default(writer, tc)?;163 write!(writer, ",")?;164 uint256::solidity_default(writer, tc)?;165 write!(writer, ")")166 }167}168169impl SolidityTupleType for Property {170 fn names(tc: &TypeCollector) -> Vec<string> {171 let mut collected = Vec::with_capacity(Self::len());172 {173 let mut out = string::new();174 string::solidity_name(&mut out, tc).expect("no fmt error");175 collected.push(out);176 }177 {178 let mut out = string::new();179 bytes::solidity_name(&mut out, tc).expect("no fmt error");180 collected.push(out);181 }182 collected183 }184185 fn len() -> usize {186 2187 }188}1use super::{TypeCollector, SolidityTypeName, SolidityType, StructCollect};2use crate::{sealed, types::*};3use core::fmt;4use primitive_types::{U256, H160};56macro_rules! solidity_type_name {7 ($($ty:ty => $name:literal $simple:literal = $default:literal),* $(,)?) => {8 $(9 impl SolidityTypeName for $ty {10 fn solidity_name(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {11 write!(writer, $name)12 }13 fn is_simple() -> bool {14 $simple15 }16 fn solidity_default(writer: &mut impl core::fmt::Write, _tc: &TypeCollector) -> core::fmt::Result {17 write!(writer, $default)18 }19 }2021 impl StructCollect for $ty {22 fn name() -> String {23 $name.to_string()24 }2526 fn declaration() -> String {27 String::default()28 }29 }30 )*31 };32}3334solidity_type_name! {35 u8 => "uint8" true = "0",36 u32 => "uint32" true = "0",37 u64 => "uint64" true = "0",38 u128 => "uint128" true = "0",39 U256 => "uint256" true = "0",40 bytes4 => "bytes4" true = "bytes4(0)",41 H160 => "address" true = "0x0000000000000000000000000000000000000000",42 string => "string" false = "\"\"",43 bytes => "bytes" false = "hex\"\"",44 bool => "bool" true = "false",45}4647impl SolidityTypeName for void {48 fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {49 Ok(())50 }51 fn is_simple() -> bool {52 true53 }54 fn solidity_default(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {55 Ok(())56 }57 fn is_void() -> bool {58 true59 }60}6162impl<T: SolidityTypeName + sealed::CanBePlacedInVec> SolidityTypeName for Vec<T> {63 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {64 T::solidity_name(writer, tc)?;65 write!(writer, "[]")66 }67 fn is_simple() -> bool {68 false69 }70 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {71 write!(writer, "new ")?;72 T::solidity_name(writer, tc)?;73 write!(writer, "[](0)")74 }75}7677macro_rules! count {78 () => (0usize);79 ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));80}8182macro_rules! impl_tuples {83 ($($ident:ident)+) => {84 impl<$($ident: SolidityTypeName + 'static),+> SolidityType for ($($ident,)+) {85 fn names(tc: &TypeCollector) -> Vec<string> {86 let mut collected = Vec::with_capacity(Self::len());87 $({88 let mut out = string::new();89 $ident::solidity_name(&mut out, tc).expect("no fmt error");90 collected.push(out);91 })*;92 collected93 }9495 fn len() -> usize {96 count!($($ident)*)97 }98 }99 impl<$($ident: SolidityTypeName + 'static),+> SolidityTypeName for ($($ident,)+) {100 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {101 write!(writer, "{}", tc.collect_tuple::<Self>())102 }103 fn is_simple() -> bool {104 false105 }106 #[allow(unused_assignments)]107 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {108 write!(writer, "{}(", tc.collect_tuple::<Self>())?;109 let mut first = true;110 $(111 if !first {112 write!(writer, ",")?;113 } else {114 first = false;115 }116 <$ident>::solidity_default(writer, tc)?;117 )*118 write!(writer, ")")119 }120 }121 };122}123124impl_tuples! {A}125impl_tuples! {A B}126impl_tuples! {A B C}127impl_tuples! {A B C D}128impl_tuples! {A B C D E}129impl_tuples! {A B C D E F}130impl_tuples! {A B C D E F G}131impl_tuples! {A B C D E F G H}132impl_tuples! {A B C D E F G H I}133impl_tuples! {A B C D E F G H I J}134135impl sealed::CanBePlacedInVec for Property {}136impl StructCollect for Property {137 fn name() -> String {138 "Property".into()139 }140141 fn declaration() -> String {142 let mut str = String::new();143 writeln!(str, "/// @dev Property struct").unwrap();144 writeln!(str, "struct {} {{", Self::name()).unwrap();145 writeln!(str, "\tstring key;").unwrap();146 writeln!(str, "\tbytes value;").unwrap();147 writeln!(str, "}}").unwrap();148 str149 }150}151152impl SolidityTypeName for Property {153 fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {154 write!(writer, "{}", tc.collect_struct::<Self>())155 }156157 fn is_simple() -> bool {158 false159 }160161 fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {162 write!(writer, "{}(", tc.collect_struct::<Self>())?;163 address::solidity_default(writer, tc)?;164 write!(writer, ",")?;165 uint256::solidity_default(writer, tc)?;166 write!(writer, ")")167 }168}169170impl SolidityTupleType for Property {171 fn names(tc: &TypeCollector) -> Vec<string> {172 let mut collected = Vec::with_capacity(Self::len());173 {174 let mut out = string::new();175 string::solidity_name(&mut out, tc).expect("no fmt error");176 collected.push(out);177 }178 {179 let mut out = string::new();180 bytes::solidity_name(&mut out, tc).expect("no fmt error");181 collected.push(out);182 }183 collected184 }185186 fn len() -> usize {187 2188 }189}crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth--- a/crates/evm-coder/tests/abi_derive_generation.rs
+++ b/crates/evm-coder/tests/abi_derive_generation.rs
@@ -57,10 +57,16 @@
_b: TypeStruct2DynamicParam,
}
+/// Some docs
+/// At multi
+/// line
#[derive(AbiCoder, PartialEq, Debug)]
struct TypeStruct3DerivedMixedParam {
+ /// Docs for A
_a: TypeStruct1SimpleParam,
+ /// Docs for B
_b: TypeStruct2DynamicParam,
+ /// Docs for C
_c: TypeStruct2MixedParam,
}
pallets/common/src/eth.rsdiffbeforeafterboth--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -113,6 +113,7 @@
}
}
+/// Cross account struct
#[derive(Debug, Default, AbiCoder)]
pub struct EthCrossAccount {
pub(crate) eth: address,