floem_reactive/
impls.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::{Memo, ReadSignal, RwSignal, SignalUpdate, SignalWith, WriteSignal};

// Unary operation macro
macro_rules! impl_unary_op {
    ($signal_type:ident, $trait:ident, $method:ident, $op:tt) => {
        impl<T: 'static> std::ops::$trait for $signal_type<T>
        where
            for<'a> &'a T: std::ops::$trait< Output = T>
        {
            type Output = T;

            fn $method(self) -> Self::Output {
                self.with(|val| $op  val)
            }
        }
    };
}

// Binary operation macro
macro_rules! impl_bin_op {
    ($signal_type:ident, $trait:ident, $method:ident, $op:tt) => {
        impl<T: std::ops::$trait<Output = T> + 'static> std::ops::$trait<T> for $signal_type<T>
        where
            for<'a> &'a T: std::ops::$trait<T, Output = T>
        {
            type Output = T;
            fn $method(self, rhs: T) -> Self::Output {
                self.with(|val| val $op rhs)
            }
        }
    };
}

// Assignment operation macro
macro_rules! impl_assign_op {
    ($signal_type:ident, $trait:ident, $method:ident, $op:tt) => {
        impl<T: std::ops::$trait + 'static> std::ops::$trait<T> for $signal_type<T> {
            fn $method(&mut self, rhs: T) {
                self.update(|val| *val $op rhs);
            }
        }
    };
}

// PartialEq implementation macro
macro_rules! impl_partial_eq {
    ($signal_type:ident) => {
        impl<T: PartialEq + 'static> PartialEq<T> for $signal_type<T> {
            fn eq(&self, other: &T) -> bool {
                self.with(|val| *val == *other)
            }
        }
    };
}
// Display implementation macro
macro_rules! impl_display {
    ($signal_type:ident) => {
        impl<T: std::fmt::Display + 'static> std::fmt::Display for $signal_type<T> {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                self.with(|val| std::fmt::Display::fmt(val, f))
            }
        }
    };
}

// Macro for implementing all binary operations and PartialEq
macro_rules! impl_with_ops {
    ($signal_type:ident) => {
        impl_bin_op!($signal_type, Add, add, +);
        impl_bin_op!($signal_type, Sub, sub, -);
        impl_bin_op!($signal_type, Mul, mul, *);
        impl_bin_op!($signal_type, Div, div, /);
        impl_bin_op!($signal_type, Rem, rem, %);
        impl_bin_op!($signal_type, BitAnd, bitand, &);
        impl_bin_op!($signal_type, BitOr, bitor, |);
        impl_bin_op!($signal_type, BitXor, bitxor, ^);
        impl_bin_op!($signal_type, Shl, shl, <<);
        impl_bin_op!($signal_type, Shr, shr, >>);
        impl_unary_op!($signal_type, Not, not, !);
        impl_unary_op!($signal_type, Neg, neg, -);
        impl_partial_eq!($signal_type);
        impl_display!($signal_type);
    };
}

// Macro for implementing all assignment operations
macro_rules! impl_assign_ops {
    ($signal_type:ident) => {
        impl_assign_op!($signal_type, AddAssign, add_assign, +=);
        impl_assign_op!($signal_type, SubAssign, sub_assign, -=);
        impl_assign_op!($signal_type, MulAssign, mul_assign, *=);
        impl_assign_op!($signal_type, DivAssign, div_assign, /=);
        impl_assign_op!($signal_type, RemAssign, rem_assign, %=);
        impl_assign_op!($signal_type, BitAndAssign, bitand_assign, &=);
        impl_assign_op!($signal_type, BitOrAssign, bitor_assign, |=);
        impl_assign_op!($signal_type, BitXorAssign, bitxor_assign, ^=);
        impl_assign_op!($signal_type, ShlAssign, shl_assign, <<=);
        impl_assign_op!($signal_type, ShrAssign, shr_assign, >>=);
    };
}

macro_rules! impl_all_ops {
    ($signal_type:ident) => {
        impl_assign_ops!($signal_type);
        impl_with_ops!($signal_type);
    };
}

impl_all_ops!(RwSignal);
impl_assign_ops!(WriteSignal);
impl_with_ops!(ReadSignal);
impl_with_ops!(Memo);