1use super::*;
2
3#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
4pub struct Integer {
5 pub value: isize,
6}
7
8impl 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}