From 446756c7e18df3d342e85f5c021f6ebe6352eb5d Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Tue, 16 Sep 2025 23:54:04 +0200 Subject: [PATCH] fix: Added missing enum tuple variant check and error --- lua_typed_macro/Cargo.toml | 2 +- lua_typed_macro/src/lib.rs | 70 +++++++++++++++++++----------- tests/ui/tuple_enum_variant.rs | 12 +++++ tests/ui/tuple_enum_variant.stderr | 11 +++++ tests/ui/tuple_struct.stderr | 2 +- 5 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 tests/ui/tuple_enum_variant.rs create mode 100644 tests/ui/tuple_enum_variant.stderr diff --git a/lua_typed_macro/Cargo.toml b/lua_typed_macro/Cargo.toml index 7518917..f89da8e 100644 --- a/lua_typed_macro/Cargo.toml +++ b/lua_typed_macro/Cargo.toml @@ -9,5 +9,5 @@ proc-macro = true [dependencies] proc-macro2 = "1.0.101" quote = "1.0.40" -syn = "2.0.106" +syn = { version = "2.0.106", features = ["extra-traits"] } convert_case = "0.8.0" diff --git a/lua_typed_macro/src/lib.rs b/lua_typed_macro/src/lib.rs index 4f98396..2a6bc7c 100644 --- a/lua_typed_macro/src/lib.rs +++ b/lua_typed_macro/src/lib.rs @@ -7,7 +7,7 @@ use proc_macro2::TokenStream as TokenStream2; use quote::{ToTokens, quote}; use syn::{DataEnum, DataStruct, DeriveInput, LitStr, Token, parse_macro_input, spanned::Spanned}; -#[derive(Clone)] +#[derive(Debug, Clone)] struct StructField { name: syn::Ident, ty: syn::Type, @@ -76,13 +76,6 @@ impl Struct { name: syn::Ident, case: Option>, ) -> syn::Result { - if data.fields.iter().any(|field| field.ident.is_none()) { - return Err(syn::Error::new( - data.fields.span(), - "Tuple structs are not supported by Typed", - )); - } - let fields = parse_fields(data.fields, case)?; Ok(Self { @@ -179,7 +172,7 @@ impl BasicEnum { } } -#[derive(Clone)] +#[derive(Debug, Clone)] struct ExtTaggedEnumVariant { name: syn::Ident, fields: Vec, @@ -252,26 +245,44 @@ impl ExtTaggedEnum { tag: LitStr, case: Option>, ) -> syn::Result { + let (variants, err): (Vec<_>, Vec<_>) = data + .variants + .into_iter() + .map(|variant| -> syn::Result<_> { + let mut fields = parse_fields(variant.fields, case)?; + + // Force each field to be optional as they might not be used depending on the + // variant selected + fields.iter_mut().for_each(|field| field.optional = true); + + Ok(ExtTaggedEnumVariant { + name: variant.ident, + case, + fields, + }) + }) + .partition(|variant| variant.is_ok()); + + if let Some(err) = err + .into_iter() + .map(|err| err.expect_err("Should only contain err results")) + .reduce(|mut acc, err| { + acc.combine(err); + acc + }) + { + return Err(err); + } + + let variants = variants + .into_iter() + .map(|variant| variant.expect("Should only contain ok results")) + .collect(); + Ok(Self { name: name.to_owned(), tag, - variants: data - .variants - .into_iter() - .map(|variant| -> syn::Result<_> { - let mut fields = parse_fields(variant.fields, case)?; - - // Force each field to be optional as they might not be used depending on the - // variant selected - fields.iter_mut().for_each(|field| field.optional = true); - - Ok(ExtTaggedEnumVariant { - name: variant.ident, - case, - fields, - }) - }) - .try_collect()?, + variants, }) } } @@ -280,6 +291,13 @@ fn parse_fields( input: syn::Fields, case: Option>, ) -> syn::Result> { + if input.iter().any(|field| field.ident.is_none()) { + return Err(syn::Error::new( + input.span(), + "Tuple structs/variants are currently not supported by Typed", + )); + } + let mut fields = Vec::new(); for field in input { let mut default = false; diff --git a/tests/ui/tuple_enum_variant.rs b/tests/ui/tuple_enum_variant.rs new file mode 100644 index 0000000..a6e81db --- /dev/null +++ b/tests/ui/tuple_enum_variant.rs @@ -0,0 +1,12 @@ +use lua_typed::Typed; + +#[derive(Typed)] +#[serde(tag = "tag")] +enum Test { + A, + B(String), + C(u8), + D { test: f32 }, +} + +fn main() {} diff --git a/tests/ui/tuple_enum_variant.stderr b/tests/ui/tuple_enum_variant.stderr new file mode 100644 index 0000000..c8ccec7 --- /dev/null +++ b/tests/ui/tuple_enum_variant.stderr @@ -0,0 +1,11 @@ +error: Tuple structs/variants are currently not supported by Typed + --> tests/ui/tuple_enum_variant.rs:7:6 + | +7 | B(String), + | ^^^^^^^^ + +error: Tuple structs/variants are currently not supported by Typed + --> tests/ui/tuple_enum_variant.rs:8:6 + | +8 | C(u8), + | ^^^^ diff --git a/tests/ui/tuple_struct.stderr b/tests/ui/tuple_struct.stderr index 6e2f336..4d1d1e1 100644 --- a/tests/ui/tuple_struct.stderr +++ b/tests/ui/tuple_struct.stderr @@ -1,4 +1,4 @@ -error: Tuple structs are not supported by Typed +error: Tuple structs/variants are currently not supported by Typed --> tests/ui/tuple_struct.rs:4:16 | 4 | pub struct Test(u8);