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}