dioxus_signals/
impls.rs

1/// This macro is used to generate a `impl Default` block for any type with the function new_maybe_sync that takes a generic `T`
2///
3/// # Example
4/// ```rust
5/// use generational_box::*;
6/// use dioxus::prelude::*;
7/// use dioxus_core::Subscribers;
8///
9/// struct MyCopyValue<T, S: 'static> {
10///     value: CopyValue<T, S>,
11/// }
12///
13/// impl<T: 'static, S: Storage<T> + 'static> MyCopyValue<T, S> {
14///     fn new_maybe_sync(value: T) -> Self {
15///         Self { value: CopyValue::new_maybe_sync(value) }
16///     }
17/// }
18///
19/// impl<T, S: Storage<T> + 'static> Readable for MyCopyValue<T, S> {
20///     type Target = T;
21///     type Storage = S;
22///
23///     fn try_read_unchecked(
24///         &self,
25///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
26///         self.value.try_read_unchecked()
27///     }
28///
29///     fn try_peek_unchecked(
30///         &self,
31///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
32///         self.value.try_read_unchecked()
33///     }
34///
35///     fn subscribers(&self) -> Subscribers where T: 'static {
36///         self.value.subscribers()
37///     }
38/// }
39///
40/// default_impl!(MyCopyValue<T, S: Storage<T>>);
41/// ```
42#[macro_export]
43macro_rules! default_impl {
44    (
45        $ty:ident
46        // Accept generics
47        < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?>
48        // Accept extra bounds
49        $(
50            where
51                $(
52                    $extra_bound_ty:ident: $extra_bound:path
53                ),+
54        )?
55    ) => {
56        impl<T: Default + 'static
57            $(, $gen $(: $gen_bound)?)*
58        > Default for $ty <T $(, $gen)*>
59        $(
60            where
61                $(
62                    $extra_bound_ty: $extra_bound
63                ),+
64        )?
65        {
66            #[track_caller]
67            fn default() -> Self {
68                Self::new_maybe_sync(Default::default())
69            }
70        }
71    }
72}
73
74/// 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`
75///
76/// # Example
77/// ```rust
78/// use generational_box::*;
79/// use dioxus::prelude::*;
80/// use dioxus_core::Subscribers;
81///
82/// struct MyCopyValue<T, S: 'static> {
83///     value: CopyValue<T, S>,
84/// }
85///
86/// impl<T: 'static, S: Storage<T> + 'static> Readable for MyCopyValue<T, S> where T: 'static {
87///     type Target = T;
88///     type Storage = S;
89///
90///     fn try_read_unchecked(
91///         &self,
92///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
93///         self.value.try_read_unchecked()
94///     }
95///
96///     fn try_peek_unchecked(
97///         &self,
98///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
99///         self.value.try_read_unchecked()
100///     }
101///
102///     fn subscribers(&self) -> Subscribers where T: 'static {
103///         self.value.subscribers()
104///     }
105/// }
106///
107/// read_impls!(MyCopyValue<T, S: Storage<T>>);
108/// ```
109#[macro_export]
110macro_rules! read_impls {
111    (
112        $ty:ident
113        // Accept generics
114        < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?>
115        // Accept extra bounds
116        $(
117            where
118                $(
119                    $extra_bound_ty:ident: $extra_bound:path
120                ),+
121        )?
122    ) => {
123        $crate::fmt_impls!{
124            $ty<
125                T
126                $(
127                    , $gen
128                    $(: $gen_bound)?
129                )*
130            >
131            $(
132                where
133                    $($extra_bound_ty: $extra_bound),*
134            )?
135        }
136        $crate::eq_impls!{
137            $ty<
138                T
139                $(
140                    , $gen
141                    $(: $gen_bound)?
142                )*
143            >
144            $(
145                where
146                    $($extra_bound_ty: $extra_bound),*
147            )?
148        }
149    };
150}
151
152/// This macro is used to generate `impl Display`, and `impl Debug` blocks for any Readable type that takes a generic `T`
153///
154/// # Example
155/// ```rust
156/// use generational_box::*;
157/// use dioxus::prelude::*;
158/// use dioxus_core::Subscribers;
159///
160/// struct MyCopyValue<T, S: 'static> {
161///     value: CopyValue<T, S>,
162/// }
163///
164/// impl<T: 'static, S: Storage<T> + 'static> Readable for MyCopyValue<T, S> {
165///     type Target = T;
166///     type Storage = S;
167///
168///     fn try_read_unchecked(
169///         &self,
170///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
171///         self.value.try_read_unchecked()
172///     }
173///
174///     fn try_peek_unchecked(
175///         &self,
176///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
177///         self.value.try_read_unchecked()
178///     }
179///
180///     fn subscribers(&self) -> Subscribers where T: 'static {
181///         self.value.subscribers()
182///     }
183/// }
184///
185/// fmt_impls!(MyCopyValue<T, S: Storage<T>>);
186/// ```
187#[macro_export]
188macro_rules! fmt_impls {
189    (
190        $ty:ident
191        // Accept generics
192        < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?>
193        // Accept extra bounds
194        $(
195            where
196                $(
197                    $extra_bound_ty:ident: $extra_bound:path
198                ),+
199        )?
200    ) => {
201    impl<
202        T: std::fmt::Display + 'static
203        $(, $gen $(: $gen_bound)?)*
204    > std::fmt::Display for $ty<T $(, $gen)*>
205        $(
206            where
207                $($extra_bound_ty: $extra_bound,)*
208        )?
209    {
210        #[track_caller]
211        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
212            self.with(|v| std::fmt::Display::fmt(v, f))
213        }
214    }
215
216    impl<
217        T: std::fmt::Debug + 'static
218        $(, $gen $(: $gen_bound)?)*
219    > std::fmt::Debug for $ty<T $(, $gen)*>
220        $(
221            where
222                $($extra_bound_ty: $extra_bound,)*
223        )?
224    {
225        #[track_caller]
226        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
227            self.with(|v| std::fmt::Debug::fmt(v, f))
228        }
229    }
230};
231    }
232
233/// This macro is used to generate `impl PartialEq` blocks for any Readable type that takes a generic `T`
234///
235/// # Example
236/// ```rust
237/// use generational_box::*;
238/// use dioxus::prelude::*;
239/// use dioxus_core::Subscribers;
240///
241/// struct MyCopyValue<T, S: 'static> {
242///     value: CopyValue<T, S>,
243/// }
244///
245/// impl<T: 'static, S: Storage<T> + 'static> Readable for MyCopyValue<T, S> {
246///     type Target = T;
247///     type Storage = S;
248///
249///     fn try_read_unchecked(
250///         &self,
251///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
252///         self.value.try_read_unchecked()
253///     }
254///
255///     fn try_peek_unchecked(
256///         &self,
257///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
258///         self.value.try_read_unchecked()
259///     }
260///
261///     fn subscribers(&self) -> Subscribers where T: 'static {
262///         self.value.subscribers()
263///     }
264/// }
265///
266/// eq_impls!(MyCopyValue<T, S: Storage<T>>);
267/// ```
268#[macro_export]
269macro_rules! eq_impls {
270    (
271        $ty:ident
272        // Accept generics
273        < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?>
274        // Accept extra bounds
275        $(
276            where
277                $(
278                    $extra_bound_ty:ident: $extra_bound:path
279                ),+
280        )?
281    ) => {
282        impl<
283            T: PartialEq + 'static
284            $(, $gen $(: $gen_bound)?)*
285        > PartialEq<T> for $ty<T $(, $gen)*>
286            $(
287                where
288                    $($extra_bound_ty: $extra_bound,)*
289            )?
290        {
291            #[track_caller]
292            fn eq(&self, other: &T) -> bool {
293                self.with(|v| *v == *other)
294            }
295        }
296    };
297}
298
299/// 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`
300///
301/// # Example
302/// ```rust, ignore
303/// use generational_box::*;
304/// use dioxus::prelude::*;
305///
306/// struct MyCopyValue<T, S: 'static> {
307///     value: CopyValue<T, S>,
308/// }
309///
310/// impl<T: 'static, S: Storage<T> + 'static> Readable for MyCopyValue<T, S> {
311///     type Target = T;
312///     type Storage = S;
313///
314///     fn try_read_unchecked(
315///         &self,
316///     ) -> Result<ReadableRef<'static, Self>, generational_box::BorrowError> where T: 'static {
317///         self.value.try_read_unchecked()
318///     }
319///
320///     fn peek_unchecked(&self) -> ReadableRef<'static, Self> where T: 'static {
321///         self.value.read_unchecked()
322///     }
323/// }
324///
325/// impl<T: 'static, S: Storage<T> + 'static> Writable for MyCopyValue<T, S> {
326///     fn try_write_unchecked(
327///         &self,
328///     ) -> Result<WritableRef<'static, Self>, generational_box::BorrowMutError> where T: 'static {
329///         self.value.try_write_unchecked()
330///     }
331///
332///     //...
333/// }
334///
335/// write_impls!(MyCopyValue<T, S: Storage<T>>);
336/// ```
337#[macro_export]
338macro_rules! write_impls {
339    (
340        $ty:ident
341        // Accept generics
342        < T $(, $gen:ident $(: $gen_bound:path)?)* $(,)?>
343        // Accept extra bounds
344        $(
345            where
346                $(
347                    $extra_bound_ty:ident: $extra_bound:path
348                ),+
349        )?) => {
350        impl<T: std::ops::Add<Output = T> + Copy + 'static
351        $(, $gen $(: $gen_bound)?)*
352        > std::ops::Add<T>
353            for $ty<T $(, $gen)*>
354            $(
355                where
356                    $($extra_bound_ty: $extra_bound,)*
357            )?
358        {
359            type Output = T;
360
361            #[track_caller]
362            fn add(self, rhs: T) -> Self::Output {
363                self.with(|v| *v + rhs)
364            }
365        }
366
367        impl<T: std::ops::Add<Output = T> + Copy + 'static
368        $(, $gen $(: $gen_bound)?)*
369        > std::ops::AddAssign<T>
370            for $ty<T $(, $gen)*>
371            $(
372                where
373                    $($extra_bound_ty: $extra_bound,)*
374            )?
375        {
376            #[track_caller]
377            fn add_assign(&mut self, rhs: T) {
378                self.with_mut(|v| *v = *v + rhs)
379            }
380        }
381
382        impl<T: std::ops::Sub<Output = T> + Copy + 'static
383        $(, $gen $(: $gen_bound)?)*
384        > std::ops::SubAssign<T>
385            for $ty<T $(, $gen)*>
386            $(
387                where
388                    $($extra_bound_ty: $extra_bound,)*
389            )?
390        {
391            #[track_caller]
392            fn sub_assign(&mut self, rhs: T) {
393                self.with_mut(|v| *v = *v - rhs)
394            }
395        }
396
397        impl<T: std::ops::Sub<Output = T> + Copy + 'static
398        $(, $gen $(: $gen_bound)?)*
399        > std::ops::Sub<T>
400            for $ty<T $(, $gen)*>
401            $(
402                where
403                    $($extra_bound_ty: $extra_bound,)*
404            )?
405        {
406            type Output = T;
407
408            #[track_caller]
409            fn sub(self, rhs: T) -> Self::Output {
410                self.with(|v| *v - rhs)
411            }
412        }
413
414        impl<T: std::ops::Mul<Output = T> + Copy + 'static
415        $(, $gen $(: $gen_bound)?)*
416        > std::ops::MulAssign<T>
417            for $ty<T $(, $gen)*>
418            $(
419                where
420                    $($extra_bound_ty: $extra_bound,)*
421            )?
422        {
423            #[track_caller]
424            fn mul_assign(&mut self, rhs: T) {
425                self.with_mut(|v| *v = *v * rhs)
426            }
427        }
428
429        impl<T: std::ops::Mul<Output = T> + Copy + 'static
430        $(, $gen $(: $gen_bound)?)*
431        > std::ops::Mul<T>
432            for $ty<T $(, $gen)*>
433            $(
434                where
435                    $($extra_bound_ty: $extra_bound,)*
436            )?
437        {
438            type Output = T;
439
440            #[track_caller]
441            fn mul(self, rhs: T) -> Self::Output {
442                self.with(|v| *v * rhs)
443            }
444        }
445
446        impl<T: std::ops::Div<Output = T> + Copy + 'static
447        $(, $gen $(: $gen_bound)?)*
448        > std::ops::DivAssign<T>
449            for $ty<T $(, $gen)*>
450            $(
451                where
452                    $($extra_bound_ty: $extra_bound,)*
453            )?
454        {
455            #[track_caller]
456            fn div_assign(&mut self, rhs: T) {
457                self.with_mut(|v| *v = *v / rhs)
458            }
459        }
460
461        impl<T: std::ops::Div<Output = T> + Copy + 'static
462        $(, $gen $(: $gen_bound)?)*
463        > std::ops::Div<T>
464            for $ty<T $(, $gen)*>
465            $(
466                where
467                    $($extra_bound_ty: $extra_bound,)*
468            )?
469        {
470            type Output = T;
471
472            #[track_caller]
473            fn div(self, rhs: T) -> Self::Output {
474                self.with(|v| *v / rhs)
475            }
476        }
477    };
478}