/// This macro is used to generate a `impl Default` block for any type with the function new_maybe_sync that takes a generic `T` /// /// # Example /// ```rust /// use generational_box::*; /// use dioxus::prelude::*; /// use dioxus_core::Subscribers; /// /// struct MyCopyValue { /// value: CopyValue, /// } /// /// impl + 'static> MyCopyValue { /// fn new_maybe_sync(value: T) -> Self { /// Self { value: CopyValue::new_maybe_sync(value) } /// } /// } /// /// impl + 'static> Readable for MyCopyValue { /// type Target = T; /// type Storage = S; /// /// fn try_read_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn try_peek_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn subscribers(&self) -> Subscribers where T: 'static { /// self.value.subscribers() /// } /// } /// /// default_impl!(MyCopyValue>); /// ``` #[macro_export] macro_rules! default_impl { ( $ty:ident // Accept generics < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?> // Accept extra bounds $( where $( $extra_bound_ty:ident: $extra_bound:path ),+ )? ) => { impl Default for $ty $( where $( $extra_bound_ty: $extra_bound ),+ )? { #[track_caller] fn default() -> Self { Self::new_maybe_sync(Default::default()) } } } } /// This macro is used to generate `impl Display`, `impl Debug`, `impl PartialEq`, and `impl Eq` blocks for any Readable type that takes a generic `T` /// /// # Example /// ```rust /// use generational_box::*; /// use dioxus::prelude::*; /// use dioxus_core::Subscribers; /// /// struct MyCopyValue { /// value: CopyValue, /// } /// /// impl + 'static> Readable for MyCopyValue where T: 'static { /// type Target = T; /// type Storage = S; /// /// fn try_read_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn try_peek_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn subscribers(&self) -> Subscribers where T: 'static { /// self.value.subscribers() /// } /// } /// /// read_impls!(MyCopyValue>); /// ``` #[macro_export] macro_rules! read_impls { ( $ty:ident // Accept generics < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?> // Accept extra bounds $( where $( $extra_bound_ty:ident: $extra_bound:path ),+ )? ) => { $crate::fmt_impls!{ $ty< T $( , $gen $(: $gen_bound)? )* > $( where $($extra_bound_ty: $extra_bound),* )? } $crate::eq_impls!{ $ty< T $( , $gen $(: $gen_bound)? )* > $( where $($extra_bound_ty: $extra_bound),* )? } }; } /// This macro is used to generate `impl Display`, and `impl Debug` blocks for any Readable type that takes a generic `T` /// /// # Example /// ```rust /// use generational_box::*; /// use dioxus::prelude::*; /// use dioxus_core::Subscribers; /// /// struct MyCopyValue { /// value: CopyValue, /// } /// /// impl + 'static> Readable for MyCopyValue { /// type Target = T; /// type Storage = S; /// /// fn try_read_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn try_peek_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn subscribers(&self) -> Subscribers where T: 'static { /// self.value.subscribers() /// } /// } /// /// fmt_impls!(MyCopyValue>); /// ``` #[macro_export] macro_rules! fmt_impls { ( $ty:ident // Accept generics < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?> // Accept extra bounds $( where $( $extra_bound_ty:ident: $extra_bound:path ),+ )? ) => { impl< T: std::fmt::Display + 'static $(, $gen $(: $gen_bound)?)* > std::fmt::Display for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| std::fmt::Display::fmt(v, f)) } } impl< T: std::fmt::Debug + 'static $(, $gen $(: $gen_bound)?)* > std::fmt::Debug for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| std::fmt::Debug::fmt(v, f)) } } }; } /// This macro is used to generate `impl PartialEq` blocks for any Readable type that takes a generic `T` /// /// # Example /// ```rust /// use generational_box::*; /// use dioxus::prelude::*; /// use dioxus_core::Subscribers; /// /// struct MyCopyValue { /// value: CopyValue, /// } /// /// impl + 'static> Readable for MyCopyValue { /// type Target = T; /// type Storage = S; /// /// fn try_read_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn try_peek_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn subscribers(&self) -> Subscribers where T: 'static { /// self.value.subscribers() /// } /// } /// /// eq_impls!(MyCopyValue>); /// ``` #[macro_export] macro_rules! eq_impls { ( $ty:ident // Accept generics < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?> // Accept extra bounds $( where $( $extra_bound_ty:ident: $extra_bound:path ),+ )? ) => { impl< T: PartialEq + 'static $(, $gen $(: $gen_bound)?)* > PartialEq for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn eq(&self, other: &T) -> bool { self.with(|v| *v == *other) } } }; } /// This macro is used to generate `impl Add`, `impl AddAssign`, `impl Sub`, `impl SubAssign`, `impl Mul`, `impl MulAssign`, `impl Div`, and `impl DivAssign` blocks for any Writable type that takes a generic `T` /// /// # Example /// ```rust, ignore /// use generational_box::*; /// use dioxus::prelude::*; /// /// struct MyCopyValue { /// value: CopyValue, /// } /// /// impl + 'static> Readable for MyCopyValue { /// type Target = T; /// type Storage = S; /// /// fn try_read_unchecked( /// &self, /// ) -> Result, generational_box::BorrowError> where T: 'static { /// self.value.try_read_unchecked() /// } /// /// fn peek_unchecked(&self) -> ReadableRef<'static, Self> where T: 'static { /// self.value.read_unchecked() /// } /// } /// /// impl + 'static> Writable for MyCopyValue { /// fn try_write_unchecked( /// &self, /// ) -> Result, generational_box::BorrowMutError> where T: 'static { /// self.value.try_write_unchecked() /// } /// /// //... /// } /// /// write_impls!(MyCopyValue>); /// ``` #[macro_export] macro_rules! write_impls { ( $ty:ident // Accept generics < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?> // Accept extra bounds $( where $( $extra_bound_ty:ident: $extra_bound:path ),+ )?) => { impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::Add for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { type Output = T; #[track_caller] fn add(self, rhs: T) -> Self::Output { self.with(|v| *v + rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::AddAssign for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn add_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v + rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::SubAssign for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn sub_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v - rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::Sub for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { type Output = T; #[track_caller] fn sub(self, rhs: T) -> Self::Output { self.with(|v| *v - rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::MulAssign for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn mul_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v * rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::Mul for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { type Output = T; #[track_caller] fn mul(self, rhs: T) -> Self::Output { self.with(|v| *v * rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::DivAssign for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { #[track_caller] fn div_assign(&mut self, rhs: T) { self.with_mut(|v| *v = *v / rhs) } } impl + Copy + 'static $(, $gen $(: $gen_bound)?)* > std::ops::Div for $ty $( where $($extra_bound_ty: $extra_bound,)* )? { type Output = T; #[track_caller] fn div(self, rhs: T) -> Self::Output { self.with(|v| *v / rhs) } } }; }