1use crate::util;
2use crate::Value;
3use std::ops;
4
5impl ops::Add for &Value {
6 type Output = Value;
7
8 fn add(self, rhs: Self) -> Self::Output {
9 match (&self, &rhs) {
10 (Value::Missing, _) => Value::Missing,
12 (_, Value::Missing) => Value::Missing,
13 (Value::Null, _) => Value::Null,
14 (_, Value::Null) => Value::Null,
15 (Value::Integer(l), Value::Integer(r)) => Value::Integer(l + r),
16 (Value::Real(l), Value::Real(r)) => Value::Real(*l + *r),
17 (Value::Decimal(l), Value::Decimal(r)) => {
18 Value::Decimal(Box::new(l.as_ref() + r.as_ref()))
19 }
20 (Value::Integer(_), Value::Real(_)) => &util::coerce_int_to_real(self) + rhs,
21 (Value::Integer(_), Value::Decimal(_)) => {
22 &util::coerce_int_or_real_to_decimal(self) + rhs
23 }
24 (Value::Real(_), Value::Decimal(_)) => &util::coerce_int_or_real_to_decimal(self) + rhs,
25 (Value::Real(_), Value::Integer(_)) => self + &util::coerce_int_to_real(rhs),
26 (Value::Decimal(_), Value::Integer(_)) => {
27 self + &util::coerce_int_or_real_to_decimal(rhs)
28 }
29 (Value::Decimal(_), Value::Real(_)) => self + &util::coerce_int_or_real_to_decimal(rhs),
30 _ => Value::Missing, }
32 }
33}
34
35impl ops::AddAssign<&Value> for Value {
36 fn add_assign(&mut self, rhs: &Value) {
37 match (self, &rhs) {
38 (Value::Missing, _) => {}
40 (this, Value::Missing) => *this = Value::Missing,
41 (Value::Null, _) => {}
42 (this, Value::Null) => *this = Value::Null,
43
44 (Value::Integer(l), Value::Integer(r)) => l.add_assign(r),
45
46 (Value::Real(l), Value::Real(r)) => l.add_assign(r),
47 (Value::Real(l), Value::Integer(i)) => l.add_assign(*i as f64),
48
49 (Value::Decimal(l), Value::Decimal(r)) => l.add_assign(r.as_ref()),
50 (Value::Decimal(l), Value::Integer(i)) => l.add_assign(rust_decimal::Decimal::from(*i)),
51 (Value::Decimal(l), Value::Real(r)) => match util::coerce_f64_to_decimal(r) {
52 Some(d) => l.add_assign(d),
53 None => todo!(),
54 },
55
56 (this, Value::Real(r)) => {
57 *this = match &this {
58 Value::Integer(l) => Value::from((*l as f64) + r.0),
59 _ => Value::Missing,
60 };
61 }
62 (this, Value::Decimal(r)) => {
63 *this = match &this {
64 Value::Integer(l) => {
65 Value::Decimal(Box::new(rust_decimal::Decimal::from(*l) + r.as_ref()))
66 }
67 Value::Real(l) => match util::coerce_f64_to_decimal(&l.0) {
68 None => Value::Missing,
69 Some(d) => Value::Decimal(Box::new(d + r.as_ref())),
70 },
71 _ => Value::Missing,
72 };
73 }
74 (this, _) => *this = Value::Missing, }
76 }
77}
78
79pub trait UnaryPlus {
80 type Output;
81
82 fn positive(self) -> Self::Output;
83}
84
85impl UnaryPlus for Value {
86 type Output = Self;
87 fn positive(self) -> Self::Output {
88 match self {
89 Value::Null => Value::Null,
90 Value::Missing => Value::Missing,
91 Value::Integer(_) | Value::Real(_) | Value::Decimal(_) => self,
92 _ => Value::Missing, }
94 }
95}
96
97impl ops::Sub for &Value {
98 type Output = Value;
99
100 fn sub(self, rhs: Self) -> Self::Output {
101 match (&self, &rhs) {
102 (Value::Missing, _) => Value::Missing,
104 (_, Value::Missing) => Value::Missing,
105 (Value::Null, _) => Value::Null,
106 (_, Value::Null) => Value::Null,
107 (Value::Integer(l), Value::Integer(r)) => Value::Integer(l - r),
108 (Value::Real(l), Value::Real(r)) => Value::Real(*l - *r),
109 (Value::Decimal(l), Value::Decimal(r)) => {
110 Value::Decimal(Box::new(l.as_ref() - r.as_ref()))
111 }
112 (Value::Integer(_), Value::Real(_)) => &util::coerce_int_to_real(self) - rhs,
113 (Value::Integer(_), Value::Decimal(_)) => {
114 &util::coerce_int_or_real_to_decimal(self) - rhs
115 }
116 (Value::Real(_), Value::Decimal(_)) => &util::coerce_int_or_real_to_decimal(self) - rhs,
117 (Value::Real(_), Value::Integer(_)) => self - &util::coerce_int_to_real(rhs),
118 (Value::Decimal(_), Value::Integer(_)) => {
119 self - &util::coerce_int_or_real_to_decimal(rhs)
120 }
121 (Value::Decimal(_), Value::Real(_)) => self - &util::coerce_int_or_real_to_decimal(rhs),
122 _ => Value::Missing, }
124 }
125}
126
127impl ops::Mul for &Value {
128 type Output = Value;
129
130 fn mul(self, rhs: Self) -> Self::Output {
131 match (&self, &rhs) {
132 (Value::Missing, _) => Value::Missing,
134 (_, Value::Missing) => Value::Missing,
135 (Value::Null, _) => Value::Null,
136 (_, Value::Null) => Value::Null,
137 (Value::Integer(l), Value::Integer(r)) => Value::Integer(l * r),
138 (Value::Real(l), Value::Real(r)) => Value::Real(*l * *r),
139 (Value::Decimal(l), Value::Decimal(r)) => {
140 Value::Decimal(Box::new(l.as_ref() * r.as_ref()))
141 }
142 (Value::Integer(_), Value::Real(_)) => &util::coerce_int_to_real(self) * rhs,
143 (Value::Integer(_), Value::Decimal(_)) => {
144 &util::coerce_int_or_real_to_decimal(self) * rhs
145 }
146 (Value::Real(_), Value::Decimal(_)) => &util::coerce_int_or_real_to_decimal(self) * rhs,
147 (Value::Real(_), Value::Integer(_)) => self * &util::coerce_int_to_real(rhs),
148 (Value::Decimal(_), Value::Integer(_)) => {
149 self * &util::coerce_int_or_real_to_decimal(rhs)
150 }
151 (Value::Decimal(_), Value::Real(_)) => self * &util::coerce_int_or_real_to_decimal(rhs),
152 _ => Value::Missing, }
154 }
155}
156
157impl ops::Div for &Value {
158 type Output = Value;
159
160 fn div(self, rhs: Self) -> Self::Output {
161 match (&self, &rhs) {
162 (Value::Missing, _) => Value::Missing,
164 (_, Value::Missing) => Value::Missing,
165 (Value::Null, _) => Value::Null,
166 (_, Value::Null) => Value::Null,
167 (Value::Integer(l), Value::Integer(r)) => Value::Integer(l / r),
168 (Value::Real(l), Value::Real(r)) => Value::Real(*l / *r),
169 (Value::Decimal(l), Value::Decimal(r)) => {
170 Value::Decimal(Box::new(l.as_ref() / r.as_ref()))
171 }
172 (Value::Integer(_), Value::Real(_)) => &util::coerce_int_to_real(self) / rhs,
173 (Value::Integer(_), Value::Decimal(_)) => {
174 &util::coerce_int_or_real_to_decimal(self) / rhs
175 }
176 (Value::Real(_), Value::Decimal(_)) => &util::coerce_int_or_real_to_decimal(self) / rhs,
177 (Value::Real(_), Value::Integer(_)) => self / &util::coerce_int_to_real(rhs),
178 (Value::Decimal(_), Value::Integer(_)) => {
179 self / &util::coerce_int_or_real_to_decimal(rhs)
180 }
181 (Value::Decimal(_), Value::Real(_)) => self / &util::coerce_int_or_real_to_decimal(rhs),
182 _ => Value::Missing, }
184 }
185}
186
187impl ops::Rem for &Value {
188 type Output = Value;
189
190 fn rem(self, rhs: Self) -> Self::Output {
191 match (&self, &rhs) {
192 (Value::Missing, _) => Value::Missing,
194 (_, Value::Missing) => Value::Missing,
195 (Value::Null, _) => Value::Null,
196 (_, Value::Null) => Value::Null,
197 (Value::Integer(l), Value::Integer(r)) => Value::Integer(l % r),
198 (Value::Real(l), Value::Real(r)) => Value::Real(*l % *r),
199 (Value::Decimal(l), Value::Decimal(r)) => {
200 Value::Decimal(Box::new(l.as_ref() % r.as_ref()))
201 }
202 (Value::Integer(_), Value::Real(_)) => &util::coerce_int_to_real(self) % rhs,
203 (Value::Integer(_), Value::Decimal(_)) => {
204 &util::coerce_int_or_real_to_decimal(self) % rhs
205 }
206 (Value::Real(_), Value::Decimal(_)) => &util::coerce_int_or_real_to_decimal(self) % rhs,
207 (Value::Real(_), Value::Integer(_)) => self % &util::coerce_int_to_real(rhs),
208 (Value::Decimal(_), Value::Integer(_)) => {
209 self % &util::coerce_int_or_real_to_decimal(rhs)
210 }
211 (Value::Decimal(_), Value::Real(_)) => self % &util::coerce_int_or_real_to_decimal(rhs),
212 _ => Value::Missing, }
214 }
215}
216
217impl ops::Neg for &Value {
218 type Output = Value;
219
220 fn neg(self) -> Self::Output {
221 match self {
222 Value::Null => Value::Null,
224 Value::Missing => Value::Missing,
225 Value::Integer(i) => Value::from(-i),
226 Value::Real(f) => Value::Real(-f),
227 Value::Decimal(d) => Value::from(-d.as_ref()),
228 _ => Value::Missing, }
230 }
231}
232
233impl ops::Neg for Value {
234 type Output = Value;
235
236 fn neg(self) -> Self::Output {
237 match self {
238 Value::Null => self,
240 Value::Missing => self,
241 Value::Integer(i) => Value::from(-i),
242 Value::Real(f) => Value::Real(-f),
243 Value::Decimal(d) => Value::from(-d.as_ref()),
244 _ => Value::Missing, }
246 }
247}