rsdiff_core/traits/
eval.rs

1/*
2    Appellation: eval <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5
6pub trait EvalOnce {
7    type Output;
8
9    fn eval_once(self) -> Self::Output;
10}
11
12pub trait EvalMut: EvalOnce {
13    fn eval_mut(&mut self) -> Self::Output;
14}
15
16pub trait Eval: EvalMut {
17    fn eval(&self) -> Self::Output;
18}
19
20macro_rules! impl_eval {
21
22    ($($s:ty),*) => {
23        $(
24            impl_eval!(@impl $s);
25        )*
26    };
27
28    (@impl $s:ty) => {
29        impl EvalOnce for $s {
30            type Output = $s;
31
32            fn eval_once(self) -> Self::Output {
33                self
34            }
35        }
36
37        impl EvalMut for $s {
38            fn eval_mut(&mut self) -> Self::Output {
39                *self
40            }
41        }
42
43        impl Eval for $s {
44            fn eval(&self) -> Self::Output {
45                *self
46            }
47        }
48    };
49    (@impl $t:ident.$call:ident<$($res:tt)*>) => {
50        impl EvalOnce for $t {
51            type Output = $($res)*;
52
53            fn eval_once(self) -> Self::Output {
54                self.$call()
55            }
56        }
57
58        impl EvalMut for $t {
59            fn eval_mut(&mut self) -> Self::Output {
60                *self.$call()
61            }
62        }
63
64        impl Eval for $t {
65            fn eval(&self) -> Self::Output {
66                *self.$call()
67            }
68        }
69    };
70    ($ty:ty => $e:expr) => {
71        impl EvalOnce for $ty {
72            type Output = $ty;
73
74            fn eval_once(self) -> Self::Output {
75                $e(self)
76            }
77        }
78
79        impl EvalMut for $ty {
80            fn eval_mut(&mut self) -> Self::Output {
81                $e(*self)
82            }
83        }
84
85        impl Eval for $ty {
86            fn eval(&self) -> Self::Output {
87                $e(*self)
88            }
89        }
90    };
91}
92
93impl_eval!(
94    f32, f64, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize
95);