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