From 1dba1fabf63d63788284a1a78a2ca6a02d210a70 Mon Sep 17 00:00:00 2001 From: Guillaume Thiolliere Date: Fri, 23 Aug 2024 17:44:22 +0900 Subject: [PATCH] Fix `MaxEncodedLen` derive macro for enum with skipped variant (#622) * fix enum skip variant max encoded len * trigger CI * trigger CI This reverts commit 40f632b90663e49ef79b1d19d054c672d46b22d5. * fmt * fix warnings --- derive/src/max_encoded_len.rs | 15 ++++++++------ tests/max_encoded_len.rs | 38 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/derive/src/max_encoded_len.rs b/derive/src/max_encoded_len.rs index c3c30abd..b9bcf580 100644 --- a/derive/src/max_encoded_len.rs +++ b/derive/src/max_encoded_len.rs @@ -119,12 +119,15 @@ fn data_length_expr(data: &Data, crate_path: &syn::Path) -> proc_macro2::TokenSt // // Each variant expression's sum is computed the way an equivalent struct's would be. - let expansion = data.variants.iter().map(|variant| { - let variant_expression = fields_length_expr(&variant.fields, crate_path); - quote! { - .max(#variant_expression) - } - }); + let expansion = + data.variants.iter().filter(|variant| !should_skip(&variant.attrs)).map( + |variant| { + let variant_expression = fields_length_expr(&variant.fields, crate_path); + quote! { + .max(#variant_expression) + } + }, + ); quote! { 0_usize #( #expansion )* .saturating_add(1) diff --git a/tests/max_encoded_len.rs b/tests/max_encoded_len.rs index 6a15e95b..ceb2810c 100644 --- a/tests/max_encoded_len.rs +++ b/tests/max_encoded_len.rs @@ -246,3 +246,41 @@ fn skip_type_params() { assert_eq!(SomeData::::max_encoded_len(), 4); } + +#[test] +fn skip_enum_struct_test() { + #[derive(Default)] + struct NoCodecType; + + struct NoCodecNoDefaultType; + + #[derive(Encode, Decode, MaxEncodedLen)] + enum Enum { + #[codec(skip)] + A(S), + B { + #[codec(skip)] + _b1: T, + b2: u32, + }, + C(#[codec(skip)] T, u32), + } + + #[derive(Encode, Decode, MaxEncodedLen)] + struct StructNamed { + #[codec(skip)] + a: T, + b: u32, + } + + #[derive(Encode, Decode, MaxEncodedLen)] + struct StructUnnamed(#[codec(skip)] T, u32); + + assert_eq!(Enum::::max_encoded_len(), 5); + assert_eq!(StructNamed::::max_encoded_len(), 4); + assert_eq!(StructUnnamed::::max_encoded_len(), 4); + + // Use the fields to avoid unused warnings. + let _ = Enum::::A(NoCodecNoDefaultType); + let _ = StructNamed:: { a: NoCodecType, b: 0 }.a; +}