Fix store macro with struct bounds (#4572)
* Fix store macro with struct bounds * fix where clause
This commit is contained in:
1 parent
8a07a24704
commit
6cd4453662
2 files changed
+116
-6
No files matched your search
@@ -121,19 +121,19 @@ fn derive_store_struct(
|
|||||||
// Generate the transposed struct definition
|
// Generate the transposed struct definition
|
||||||
let transposed_struct = match &structure.fields {
|
let transposed_struct = match &structure.fields {
|
||||||
Fields::Named(_) => {
|
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(_) => {
|
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 => {
|
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
|
// Expand to the extension trait and its implementation for the store alongside the transposed struct
|
||||||
Ok(quote! {
|
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
|
#definitions
|
||||||
)*
|
)*
|
||||||
@@ -358,11 +358,11 @@ fn derive_store_enum(
|
|||||||
};
|
};
|
||||||
implementations.push(implementation);
|
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
|
// Expand to the extension trait and its implementation for the store alongside the transposed enum
|
||||||
Ok(quote! {
|
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
|
#definitions
|
||||||
)*
|
)*
|
||||||
|
|||||||
@@ -93,6 +93,51 @@ mod macro_tests {
|
|||||||
store.check();
|
store.check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn derive_generic_struct_with_bounds() {
|
||||||
|
#[derive(Store)]
|
||||||
|
struct Item<T: ?Sized>
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
{
|
||||||
|
checked: bool,
|
||||||
|
contents: &'static T,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[store]
|
||||||
|
impl<T: ?Sized + 'static> Store<Item<T>> {
|
||||||
|
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<bool, _> = 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() {
|
fn derive_tuple() {
|
||||||
#[derive(Store, PartialEq, Clone, Debug)]
|
#[derive(Store, PartialEq, Clone, Debug)]
|
||||||
struct Item(bool, String);
|
struct Item(bool, String);
|
||||||
@@ -232,4 +277,69 @@ mod macro_tests {
|
|||||||
let is_foo_or_bar = store.is_foo_or_bar();
|
let is_foo_or_bar = store.is_foo_or_bar();
|
||||||
store.make_foo();
|
store.make_foo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn derive_generic_enum_with_bounds() {
|
||||||
|
#[derive(Store, PartialEq, Clone, Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
enum Enum<T: ?Sized>
|
||||||
|
where
|
||||||
|
T: 'static,
|
||||||
|
{
|
||||||
|
Foo,
|
||||||
|
Bar(&'static T),
|
||||||
|
Baz { foo: i32, bar: &'static T },
|
||||||
|
FooBar(u32, &'static T),
|
||||||
|
BarFoo { foo: &'static T },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[store]
|
||||||
|
impl<T: ?Sized + 'static> Store<Enum<T>> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user