From 6d5c2da0306a6df736305efbe87cc84fcd2b2cb0 Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Mon, 15 Sep 2025 21:32:57 +0200 Subject: [PATCH] feat: Added support for flatten --- lua_typed_macro/src/lib.rs | 21 ++++++++++++++++----- tests/flatten.rs | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 tests/flatten.rs diff --git a/lua_typed_macro/src/lib.rs b/lua_typed_macro/src/lib.rs index e22d671..1d2b28e 100644 --- a/lua_typed_macro/src/lib.rs +++ b/lua_typed_macro/src/lib.rs @@ -11,6 +11,7 @@ struct StructField { ty: syn::Type, case: Option>, default: bool, + flatten: bool, } impl ToTokens for StructField { @@ -23,13 +24,19 @@ impl ToTokens for StructField { let ty = &self.ty; - let default = if self.default { "?" } else { "" }; + if self.flatten { + tokens.extend(quote! { + <#ty as Typed>::generate_members().unwrap_or("".to_string()) + }); + } else { + let default = if self.default { "?" } else { "" }; - let format = format!("---@field {} {{}}{}\n", name, default); + let format = format!("---@field {} {{}}{}\n", name, default); - tokens.extend(quote! { - format!(#format, <#ty as Typed>::type_name()) - }); + tokens.extend(quote! { + format!(#format, <#ty as Typed>::type_name()) + }); + } } } @@ -168,6 +175,7 @@ pub fn typed(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let mut fields = Vec::new(); for field in data_struct.fields { let mut default = false; + let mut flatten = false; for attr in &field.attrs { if attr.path().is_ident("serde") && let Err(err) = attr.parse_nested_meta(|meta| { @@ -177,6 +185,8 @@ pub fn typed(input: proc_macro::TokenStream) -> proc_macro::TokenStream { meta.input.parse::()?; meta.input.parse::()?; } + } else if meta.path.is_ident("flatten") { + flatten = true; } Ok(()) @@ -191,6 +201,7 @@ pub fn typed(input: proc_macro::TokenStream) -> proc_macro::TokenStream { ty: field.ty, case, default, + flatten, }); } diff --git a/tests/flatten.rs b/tests/flatten.rs new file mode 100644 index 0000000..f3b2c97 --- /dev/null +++ b/tests/flatten.rs @@ -0,0 +1,24 @@ +use lua_typed::Typed; + +#[derive(Typed)] +pub struct B { + pub hello: String, + pub world: bool, +} + +#[derive(Typed)] +pub struct A { + #[serde(flatten)] + pub b: B, + pub cool: u32, +} + +#[test] +fn flatten() { + insta::assert_snapshot!(::generate_full().unwrap(), @r" + ---@class A + ---@field hello string + ---@field world boolean + ---@field cool integer + "); +}