difftreelog
misc: Check enum is repr(u8)
in: master
2 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,10 +2,10 @@
pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
let name = &ast.ident;
- let docs = extract_docs(&ast.attrs)?;
match &ast.data {
syn::Data::Struct(ds) => {
+ let docs = extract_docs(&ast.attrs)?;
let (is_named_fields, field_names, field_types, field_docs, params_count) =
match ds.fields {
syn::Fields::Named(ref fields) => Ok((
@@ -57,11 +57,61 @@
#solidity_struct_collect
})
}
- syn::Data::Enum(_) => Err(syn::Error::new(name.span(), "Enums not supported")),
+ syn::Data::Enum(de) => {
+ let _ = check_repr_u8(name, &ast.attrs)?;
+
+ // dbg!(de);
+ Ok(quote!())
+ }
syn::Data::Union(_) => Err(syn::Error::new(name.span(), "Unions not supported")),
}
}
+fn check_repr_u8(name: &syn::Ident, attrs: &Vec<syn::Attribute>) -> syn::Result<()> {
+ let repr_u8 = attrs
+ .iter()
+ .filter_map(|attr| {
+ if let Some(ps) = attr.path.segments.first() {
+ if ps.ident == "repr" {
+ let meta = match attr.parse_meta() {
+ Ok(meta) => meta,
+ Err(e) => return Some(Err(e)),
+ };
+ let is_repr_u8 = match meta {
+ syn::Meta::List(p) => {
+ p.nested
+ .iter()
+ .filter(|nm| match nm {
+ syn::NestedMeta::Meta(m) => match m {
+ syn::Meta::Path(p) => {
+ p.segments.iter().filter(|ps| ps.ident == "u8").count()
+ == 1
+ }
+ _ => false,
+ },
+ _ => false,
+ })
+ .count() == 1
+ }
+ _ => false,
+ };
+
+ if is_repr_u8 {
+ return Some(Ok(()));
+ };
+ }
+ }
+ None::<syn::Result<()>>
+ })
+ .collect::<syn::Result<Vec<_>>>()?;
+
+ if repr_u8.len() != 1 {
+ return Err(syn::Error::new(name.span(), "Enum is not \"repr(u8)\""));
+ };
+
+ Ok(())
+}
+
fn tuple_type<'a>(
field_types: impl Iterator<Item = &'a syn::Type> + Clone,
) -> proc_macro2::TokenStream {
crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth736 }736 }737}737}738739mod test_enum {740 use evm_coder::AbiCoder;741742 #[derive(AbiCoder)]743 #[repr(u8)]744 enum Color {745 Red,746 Green,747 Blue = 255,748 }749750 #[test]751 fn empty() {}752}738753