symrs/expr/
integer.rs

1use super::*;
2
3#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
4pub struct Integer {
5    pub value: isize,
6}
7
8// impl Par
9//
10// impl PartialOrd<i32> for &Integer {
11//     fn partial_cmp(&self, other: &i32) -> Option<Ordering> {
12//         todo!()
13//     }
14// }
15
16impl Expr for Integer {
17    fn get_ref<'a>(&'a self) -> &'a dyn Expr {
18        self as &dyn Expr
19    }
20
21    fn known_expr(&self) -> KnownExpr {
22        KnownExpr::Integer(self)
23    }
24
25    fn as_f64(&self) -> Option<f64> {
26        Some(
27            self.value
28                .to_f64()
29                .expect("hopefully value holds within f64"),
30        )
31    }
32    fn is_one(&self) -> bool {
33        self.value == 1
34    }
35
36    fn is_neg_one(&self) -> bool {
37        self.value == -1
38    }
39
40    fn is_negative_number(&self) -> bool {
41        self.value < 0
42    }
43
44    fn is_number(&self) -> bool {
45        true
46    }
47
48    fn is_zero(&self) -> bool {
49        self.value == 0
50    }
51
52    fn for_each_arg(&self, f: &mut dyn FnMut(&dyn Arg) -> ()) {
53        f(&self.value);
54    }
55
56    fn from_args(&self, args: Vec<Box<dyn Arg>>) -> Box<dyn Expr> {
57        let val = (&*args[0]) as &dyn Any;
58        Box::new(Integer {
59            value: val
60                .downcast_ref::<isize>()
61                .expect(&format!("{}", &type_name_of_val(args[0].as_any())))
62                .clone(),
63        })
64    }
65
66    fn clone_box(&self) -> Box<dyn Expr> {
67        Box::new(self.clone())
68    }
69
70    fn str(&self) -> String {
71        self.value.to_string()
72    }
73}
74
75impl ToInteger for Integer {
76    fn to_integer(&self) -> Integer {
77        self.clone()
78    }
79}
80
81impl ToInteger for &Integer {
82    fn to_integer(&self) -> Integer {
83        (**self).clone()
84    }
85}
86
87impl Integer {
88    pub fn new_box(value: isize) -> Box<dyn Expr> {
89        Box::new(Integer { value })
90    }
91
92    pub fn new(value: isize) -> Self {
93        Integer { value }
94    }
95
96    pub fn zero() -> Integer {
97        Integer { value: 0 }
98    }
99
100    pub fn one_box() -> Box<dyn Expr> {
101        Integer::new_box(1)
102    }
103
104    pub fn zero_box() -> Box<dyn Expr> {
105        Integer::new_box(0)
106    }
107}
108
109impl std::fmt::Debug for Integer {
110    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111        write!(f, "{:?}", self.get_ref())
112    }
113}
114
115impl std::ops::Neg for Integer {
116    type Output = Integer;
117
118    fn neg(self) -> Self::Output {
119        if self.value == 0 {
120            return Integer::new(0);
121        }
122        Integer::new(-self.value)
123    }
124}
125
126impl std::ops::Neg for &Integer {
127    type Output = Integer;
128
129    fn neg(self) -> Self::Output {
130        -*self
131    }
132}
133
134impl<E: Expr> std::ops::Mul<&E> for &Integer {
135    type Output = Box<dyn Expr>;
136
137    fn mul(self, rhs: &E) -> Self::Output {
138        (self as &dyn Expr) * rhs.get_ref()
139    }
140}
141
142impl std::ops::Mul<&Box<dyn Expr>> for &Integer {
143    type Output = Box<dyn Expr>;
144
145    fn mul(self, rhs: &Box<dyn Expr>) -> Self::Output {
146        (self as &dyn Expr) * rhs.get_ref()
147    }
148}