fix: Added missing enum tuple variant check and error

This commit is contained in:
2025-09-16 23:54:04 +02:00
parent 467a037a77
commit 446756c7e1
5 changed files with 69 additions and 28 deletions

View File

@@ -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"

View File

@@ -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<convert_case::Case<'static>>,
) -> syn::Result<Self> {
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<StructField>,
@@ -252,26 +245,44 @@ impl ExtTaggedEnum {
tag: LitStr,
case: Option<convert_case::Case<'static>>,
) -> syn::Result<Self> {
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<convert_case::Case<'static>>,
) -> syn::Result<Vec<StructField>> {
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;

View File

@@ -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() {}

View File

@@ -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),
| ^^^^

View File

@@ -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);