diff --git a/packages/stores-macro/src/derive.rs b/packages/stores-macro/src/derive.rs index c3cf829d1..d30c757e3 100644 --- a/packages/stores-macro/src/derive.rs +++ b/packages/stores-macro/src/derive.rs @@ -121,19 +121,19 @@ fn derive_store_struct( // Generate the transposed struct definition let transposed_struct = match &structure.fields { Fields::Named(_) => { - quote! { #visibility struct #transposed_name #extension_generics #extension_where_clause {#(#transposed_fields),*} } + quote! { #visibility struct #transposed_name #extension_impl_generics #extension_where_clause {#(#transposed_fields),*} } } Fields::Unnamed(_) => { - quote! { #visibility struct #transposed_name #extension_generics (#(#transposed_fields),*) #extension_where_clause; } + quote! { #visibility struct #transposed_name #extension_impl_generics (#(#transposed_fields),*) #extension_where_clause; } } Fields::Unit => { - quote! {#visibility struct #transposed_name #extension_generics #extension_where_clause;} + quote! {#visibility struct #transposed_name #extension_impl_generics #extension_where_clause;} } }; // Expand to the extension trait and its implementation for the store alongside the transposed struct Ok(quote! { - #visibility trait #extension_trait_name #extension_generics where #extension_where_clause { + #visibility trait #extension_trait_name #extension_impl_generics #extension_where_clause { #( #definitions )* @@ -358,11 +358,11 @@ fn derive_store_enum( }; implementations.push(implementation); - let transposed_enum = quote! { #visibility enum #transposed_name #extension_generics #extension_where_clause {#(#transposed_variants),*} }; + let transposed_enum = quote! { #visibility enum #transposed_name #extension_impl_generics #extension_where_clause {#(#transposed_variants),*} }; // Expand to the extension trait and its implementation for the store alongside the transposed enum Ok(quote! { - #visibility trait #extension_trait_name #extension_generics where #extension_where_clause { + #visibility trait #extension_trait_name #extension_impl_generics #extension_where_clause { #( #definitions )* diff --git a/packages/stores/tests/marco.rs b/packages/stores/tests/marco.rs index 4f50e3bfb..e972c43bd 100644 --- a/packages/stores/tests/marco.rs +++ b/packages/stores/tests/marco.rs @@ -93,6 +93,51 @@ mod macro_tests { store.check(); } + fn derive_generic_struct_with_bounds() { + #[derive(Store)] + struct Item + where + T: 'static, + { + checked: bool, + contents: &'static T, + } + + #[store] + impl Store> { + fn is_checked(&self) -> bool + where + T: 'static, + { + self.checked().cloned() + } + + fn check(&mut self) + where + T: 'static, + { + self.checked().set(true); + } + } + + let mut store = use_store(|| Item { + checked: false, + contents: "Learn about stores", + }); + + let checked: Store = store.checked(); + let contents: Store<&'static str, _> = store.contents(); + let checked: bool = checked(); + let contents: &'static str = contents(); + + let ItemStoreTransposed { checked, contents } = store.transpose(); + let checked: bool = checked(); + let contents: &'static str = contents(); + + let is_checked = store.is_checked(); + store.check(); + } + fn derive_tuple() { #[derive(Store, PartialEq, Clone, Debug)] struct Item(bool, String); @@ -232,4 +277,69 @@ mod macro_tests { let is_foo_or_bar = store.is_foo_or_bar(); store.make_foo(); } + + fn derive_generic_enum_with_bounds() { + #[derive(Store, PartialEq, Clone, Debug)] + #[non_exhaustive] + enum Enum + where + T: 'static, + { + Foo, + Bar(&'static T), + Baz { foo: i32, bar: &'static T }, + FooBar(u32, &'static T), + BarFoo { foo: &'static T }, + } + + #[store] + impl Store> { + fn is_foo_or_bar(&self) -> bool + where + T: Clone + 'static, + { + matches!(self.cloned(), Enum::Foo | Enum::Bar(_)) + } + + fn make_foo(&mut self) + where + T: 'static, + { + self.set(Enum::Foo); + } + } + + let mut store = use_store(|| Enum::Bar("Hello")); + + let foo = store.is_foo(); + let bar = store.is_bar(); + let baz = store.is_baz(); + let foobar = store.is_foo_bar(); + let barfoo = store.is_bar_foo(); + + let foo = store.bar().unwrap(); + let foo: &'static str = foo(); + let bar = store.bar_foo().unwrap(); + let bar: &'static str = bar(); + + let transposed = store.transpose(); + use EnumStoreTransposed::*; + match transposed { + EnumStoreTransposed::Foo => {} + Bar(bar) => { + let bar: &'static str = bar(); + } + Baz { foo, bar } => { + let foo: i32 = foo(); + let bar: &'static str = bar(); + } + FooBar(foo, bar) => { + let foo: u32 = foo(); + let bar: &'static str = bar(); + } + BarFoo { foo } => { + let foo: &'static str = foo(); + } + } + } }