1use crate::{Memo, ReadSignal, RwSignal, SignalUpdate, SignalWith, WriteSignal};
2
3macro_rules! impl_unary_op {
5 ($signal_type:ident, $trait:ident, $method:ident, $op:tt) => {
6 impl<T: 'static> std::ops::$trait for $signal_type<T>
7 where
8 for<'a> &'a T: std::ops::$trait< Output = T>
9 {
10 type Output = T;
11
12 fn $method(self) -> Self::Output {
13 self.with(|val| $op val)
14 }
15 }
16 };
17}
18
19macro_rules! impl_bin_op {
21 ($signal_type:ident, $trait:ident, $method:ident, $op:tt) => {
22 impl<T: std::ops::$trait<Output = T> + 'static> std::ops::$trait<T> for $signal_type<T>
23 where
24 for<'a> &'a T: std::ops::$trait<T, Output = T>
25 {
26 type Output = T;
27 fn $method(self, rhs: T) -> Self::Output {
28 self.with(|val| val $op rhs)
29 }
30 }
31 };
32}
33
34macro_rules! impl_assign_op {
36 ($signal_type:ident, $trait:ident, $method:ident, $op:tt) => {
37 impl<T: std::ops::$trait + 'static> std::ops::$trait<T> for $signal_type<T> {
38 fn $method(&mut self, rhs: T) {
39 self.update(|val| *val $op rhs);
40 }
41 }
42 };
43}
44
45macro_rules! impl_partial_eq {
47 ($signal_type:ident) => {
48 impl<T: PartialEq + 'static> PartialEq<T> for $signal_type<T> {
49 fn eq(&self, other: &T) -> bool {
50 self.with(|val| *val == *other)
51 }
52 }
53 };
54}
55macro_rules! impl_display {
57 ($signal_type:ident) => {
58 impl<T: std::fmt::Display + 'static> std::fmt::Display for $signal_type<T> {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 self.with(|val| std::fmt::Display::fmt(val, f))
61 }
62 }
63 };
64}
65
66macro_rules! impl_with_ops {
68 ($signal_type:ident) => {
69 impl_bin_op!($signal_type, Add, add, +);
70 impl_bin_op!($signal_type, Sub, sub, -);
71 impl_bin_op!($signal_type, Mul, mul, *);
72 impl_bin_op!($signal_type, Div, div, /);
73 impl_bin_op!($signal_type, Rem, rem, %);
74 impl_bin_op!($signal_type, BitAnd, bitand, &);
75 impl_bin_op!($signal_type, BitOr, bitor, |);
76 impl_bin_op!($signal_type, BitXor, bitxor, ^);
77 impl_bin_op!($signal_type, Shl, shl, <<);
78 impl_bin_op!($signal_type, Shr, shr, >>);
79 impl_unary_op!($signal_type, Not, not, !);
80 impl_unary_op!($signal_type, Neg, neg, -);
81 impl_partial_eq!($signal_type);
82 impl_display!($signal_type);
83 };
84}
85
86macro_rules! impl_assign_ops {
88 ($signal_type:ident) => {
89 impl_assign_op!($signal_type, AddAssign, add_assign, +=);
90 impl_assign_op!($signal_type, SubAssign, sub_assign, -=);
91 impl_assign_op!($signal_type, MulAssign, mul_assign, *=);
92 impl_assign_op!($signal_type, DivAssign, div_assign, /=);
93 impl_assign_op!($signal_type, RemAssign, rem_assign, %=);
94 impl_assign_op!($signal_type, BitAndAssign, bitand_assign, &=);
95 impl_assign_op!($signal_type, BitOrAssign, bitor_assign, |=);
96 impl_assign_op!($signal_type, BitXorAssign, bitxor_assign, ^=);
97 impl_assign_op!($signal_type, ShlAssign, shl_assign, <<=);
98 impl_assign_op!($signal_type, ShrAssign, shr_assign, >>=);
99 };
100}
101
102macro_rules! impl_all_ops {
103 ($signal_type:ident) => {
104 impl_assign_ops!($signal_type);
105 impl_with_ops!($signal_type);
106 };
107}
108
109impl_all_ops!(RwSignal);
110impl_assign_ops!(WriteSignal);
111impl_with_ops!(ReadSignal);
112impl_with_ops!(Memo);