diff --git a/bauble_macro_util/src/lib.rs b/bauble_macro_util/src/lib.rs index d8abed1..c0fdb11 100644 --- a/bauble_macro_util/src/lib.rs +++ b/bauble_macro_util/src/lib.rs @@ -211,6 +211,7 @@ struct TypeInfo<'a> { ty: TokenStream, /// The type's generics impl_generics: &'a ImplGenerics<'a>, + has_generics: bool, where_clause: &'a WhereClause, } @@ -219,6 +220,7 @@ fn derive_fields( TypeInfo { ty, impl_generics, + has_generics, where_clause, }: TypeInfo, // The struct or variant's fields @@ -395,9 +397,15 @@ fn derive_fields( // Generate code that evaluates each field // TODO The way `impl_generics` is used here prevents the user from adding bounds directly on // the type parameters + let fields = fields.iter().map(|field| { let ident = &field.name; let default = format_ident!("default_{ident}"); + let default_call = if has_generics { + quote! { #default::#impl_generics() } + } else { + quote! { #default() } + }; match (&field.ty, flatten) { ( FieldTy::Val { @@ -438,7 +446,7 @@ fn derive_fields( allocator, ::bauble::FromBauble::from_bauble(value, allocator)?, )?, - None => #default::#impl_generics(), + None => #default_call, } }, ( @@ -463,7 +471,7 @@ fn derive_fields( ::bauble::FromBauble::from_bauble(values.#index, allocator)? )? }, - (FieldTy::AsDefault { .. }, _) => quote! { #ident: #default::#impl_generics() }, + (FieldTy::AsDefault { .. }, _) => quote! { #ident: #default_call }, } }); @@ -730,6 +738,7 @@ pub fn derive_bauble_derive_input( TypeInfo { ty: quote! { Self }, impl_generics: &impl_generics, + has_generics: generics.params.len() > 1, where_clause: &where_clause, }, &fields, @@ -854,6 +863,7 @@ pub fn derive_bauble_derive_input( TypeInfo { ty: quote! { Self::#ident }, impl_generics: &impl_generics, + has_generics: generics.params.len() > 1, where_clause: &where_clause, }, &fields, diff --git a/bauble_macros/tests/derive.rs b/bauble_macros/tests/derive.rs index 9043aa8..b666bcc 100644 --- a/bauble_macros/tests/derive.rs +++ b/bauble_macros/tests/derive.rs @@ -98,4 +98,30 @@ fn test_flattened() { Ok(Test::Bar { x: true }), simple_convert("test = true", "test", &bauble::DefaultAllocator) ); + + #[derive(FromBauble, PartialEq, Debug)] + #[bauble(flatten)] + struct Test2 { + #[bauble(attribute, default)] + count: u32, + name: String, + } + assert_eq!( + Ok(Test2 { + count: 10, + name: "foo".to_string() + }), + simple_convert( + "test = #[count = 10] \"foo\"", + "test", + &bauble::DefaultAllocator + ) + ); + assert_eq!( + Ok(Test2 { + count: 0, + name: "bar".to_string() + }), + simple_convert("test = \"bar\"", "test", &bauble::DefaultAllocator) + ); }