1use {
2 super::TryBinaryOperator,
3 crate::{
4 data::{NumericBinaryOperator, ValueError},
5 prelude::Value,
6 result::Result,
7 },
8 Value::*,
9 rust_decimal::prelude::Decimal,
10 std::cmp::Ordering,
11};
12
13impl PartialEq<Value> for f32 {
14 fn eq(&self, other: &Value) -> bool {
15 let lhs = *self;
16
17 match *other {
18 I8(rhs) => (lhs - f32::from(rhs)).abs() < f32::EPSILON,
19 I16(rhs) => (lhs - f32::from(rhs)).abs() < f32::EPSILON,
20 I32(rhs) => (lhs - (rhs as f32)).abs() < f32::EPSILON,
21 I64(rhs) => (lhs - (rhs as f32)).abs() < f32::EPSILON,
22 I128(rhs) => (lhs - (rhs as f32)).abs() < f32::EPSILON,
23 U8(rhs) => (lhs - f32::from(rhs)).abs() < f32::EPSILON,
24 U16(rhs) => (lhs - f32::from(rhs)).abs() < f32::EPSILON,
25 U32(rhs) => (lhs - (rhs as f32)).abs() < f32::EPSILON,
26 U64(rhs) => (lhs - (rhs as f32)).abs() < f32::EPSILON,
27 U128(rhs) => (lhs - (rhs as f32)).abs() < f32::EPSILON,
28 F32(rhs) => (lhs - rhs).abs() < f32::EPSILON,
29 F64(rhs) => (lhs - rhs as f32).abs() < f32::EPSILON,
30 Decimal(rhs) => Decimal::from_f32_retain(lhs).is_some_and(|x| rhs == x),
31 _ => false,
32 }
33 }
34}
35
36impl PartialOrd<Value> for f32 {
37 fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
38 match *other {
39 I8(rhs) => self.partial_cmp(&f32::from(rhs)),
40 I16(rhs) => self.partial_cmp(&f32::from(rhs)),
41 I32(rhs) => self.partial_cmp(&(rhs as f32)),
42 I64(rhs) => self.partial_cmp(&(rhs as f32)),
43 I128(rhs) => self.partial_cmp(&(rhs as f32)),
44 U8(rhs) => self.partial_cmp(&f32::from(rhs)),
45 U16(rhs) => self.partial_cmp(&f32::from(rhs)),
46 U32(rhs) => self.partial_cmp(&(rhs as f32)),
47 U64(rhs) => self.partial_cmp(&(rhs as f32)),
48 U128(rhs) => self.partial_cmp(&(rhs as f32)),
49 F64(rhs) => self.partial_cmp(&(rhs as f32)),
50 F32(rhs) => self.partial_cmp(&rhs),
51 Decimal(rhs) => Decimal::from_f32_retain(*self).and_then(|x| x.partial_cmp(&rhs)),
52 _ => None,
53 }
54 }
55}
56
57impl TryBinaryOperator for f32 {
58 type Rhs = Value;
59
60 fn try_add(&self, rhs: &Self::Rhs) -> Result<Value> {
61 let lhs = *self;
62
63 match *rhs {
64 I8(rhs) => Ok(F32(lhs + f32::from(rhs))),
65 I16(rhs) => Ok(F32(lhs + f32::from(rhs))),
66 I32(rhs) => Ok(F32(lhs + rhs as f32)),
67 I64(rhs) => Ok(F32(lhs + rhs as f32)),
68 I128(rhs) => Ok(F32(lhs + rhs as f32)),
69 U8(rhs) => Ok(F32(lhs + f32::from(rhs))),
70 U16(rhs) => Ok(F32(lhs + f32::from(rhs))),
71 U32(rhs) => Ok(F32(lhs + rhs as f32)),
72 U64(rhs) => Ok(F32(lhs + rhs as f32)),
73 U128(rhs) => Ok(F32(lhs + rhs as f32)),
74 F64(rhs) => Ok(F32(lhs + rhs as f32)),
75 F32(rhs) => Ok(F32(lhs + rhs)),
76 Decimal(rhs) => Decimal::from_f32_retain(lhs).map_or_else(
77 || Err(ValueError::FloatToDecimalConversionFailure(lhs.into()).into()),
78 |x| Ok(Decimal(x + rhs)),
79 ),
80 Null => Ok(Null),
81 _ => Err(ValueError::NonNumericMathOperation {
82 lhs: F32(lhs),
83 operator: NumericBinaryOperator::Add,
84 rhs: rhs.clone(),
85 }
86 .into()),
87 }
88 }
89
90 fn try_subtract(&self, rhs: &Self::Rhs) -> Result<Value> {
91 let lhs = *self;
92
93 match *rhs {
94 I8(rhs) => Ok(F32(lhs - f32::from(rhs))),
95 I16(rhs) => Ok(F32(lhs - f32::from(rhs))),
96 I32(rhs) => Ok(F32(lhs - rhs as f32)),
97 I64(rhs) => Ok(F32(lhs - rhs as f32)),
98 I128(rhs) => Ok(F32(lhs - rhs as f32)),
99 U8(rhs) => Ok(F32(lhs - f32::from(rhs))),
100 U16(rhs) => Ok(F32(lhs - f32::from(rhs))),
101 U32(rhs) => Ok(F32(lhs - rhs as f32)),
102 U64(rhs) => Ok(F32(lhs - rhs as f32)),
103 U128(rhs) => Ok(F32(lhs - rhs as f32)),
104 F64(rhs) => Ok(F32(lhs - rhs as f32)),
105 F32(rhs) => Ok(F32(lhs - rhs)),
106 Decimal(rhs) => Decimal::from_f32_retain(lhs).map_or_else(
107 || Err(ValueError::FloatToDecimalConversionFailure(lhs.into()).into()),
108 |x| Ok(Decimal(x - rhs)),
109 ),
110 Null => Ok(Null),
111 _ => Err(ValueError::NonNumericMathOperation {
112 lhs: F32(lhs),
113 operator: NumericBinaryOperator::Subtract,
114 rhs: rhs.clone(),
115 }
116 .into()),
117 }
118 }
119
120 fn try_multiply(&self, rhs: &Self::Rhs) -> Result<Value> {
121 let lhs = *self;
122
123 match *rhs {
124 I8(rhs) => Ok(F32(lhs * f32::from(rhs))),
125 I16(rhs) => Ok(F32(lhs * f32::from(rhs))),
126 I32(rhs) => Ok(F32(lhs * rhs as f32)),
127 I64(rhs) => Ok(F32(lhs * rhs as f32)),
128 I128(rhs) => Ok(F32(lhs * rhs as f32)),
129 U8(rhs) => Ok(F32(lhs * f32::from(rhs))),
130 U16(rhs) => Ok(F32(lhs * f32::from(rhs))),
131 U32(rhs) => Ok(F32(lhs * rhs as f32)),
132 U64(rhs) => Ok(F32(lhs * rhs as f32)),
133 U128(rhs) => Ok(F32(lhs * rhs as f32)),
134 F64(rhs) => Ok(F32(lhs * rhs as f32)),
135 F32(rhs) => Ok(F32(lhs * rhs)),
136 Interval(rhs) => Ok(Interval(lhs * rhs)),
137 Decimal(rhs) => Decimal::from_f32_retain(lhs).map_or_else(
138 || Err(ValueError::FloatToDecimalConversionFailure(lhs.into()).into()),
139 |x| Ok(Decimal(x * rhs)),
140 ),
141 Null => Ok(Null),
142 _ => Err(ValueError::NonNumericMathOperation {
143 lhs: F32(lhs),
144 operator: NumericBinaryOperator::Multiply,
145 rhs: rhs.clone(),
146 }
147 .into()),
148 }
149 }
150
151 fn try_divide(&self, rhs: &Self::Rhs) -> Result<Value> {
152 let lhs = *self;
153
154 match *rhs {
155 I8(rhs) => Ok(F32(lhs / f32::from(rhs))),
156 I16(rhs) => Ok(F32(lhs / f32::from(rhs))),
157 I32(rhs) => Ok(F32(lhs / rhs as f32)),
158 I64(rhs) => Ok(F32(lhs / rhs as f32)),
159 I128(rhs) => Ok(F32(lhs / rhs as f32)),
160 U8(rhs) => Ok(F32(lhs / f32::from(rhs))),
161 U16(rhs) => Ok(F32(lhs / f32::from(rhs))),
162 U32(rhs) => Ok(F32(lhs / rhs as f32)),
163 U64(rhs) => Ok(F32(lhs / rhs as f32)),
164 U128(rhs) => Ok(F32(lhs / rhs as f32)),
165 F64(rhs) => Ok(F32(lhs / rhs as f32)),
166 F32(rhs) => Ok(F32(lhs / rhs)),
167 Decimal(rhs) => Decimal::from_f32_retain(lhs).map_or_else(
168 || Err(ValueError::FloatToDecimalConversionFailure(lhs.into()).into()),
169 |x| Ok(Decimal(x / rhs)),
170 ),
171 Null => Ok(Null),
172 _ => Err(ValueError::NonNumericMathOperation {
173 lhs: F32(lhs),
174 operator: NumericBinaryOperator::Divide,
175 rhs: rhs.clone(),
176 }
177 .into()),
178 }
179 }
180
181 fn try_modulo(&self, rhs: &Self::Rhs) -> Result<Value> {
182 let lhs = *self;
183
184 match *rhs {
185 I8(rhs) => Ok(F32(lhs % f32::from(rhs))),
186 I16(rhs) => Ok(F32(lhs % f32::from(rhs))),
187 I32(rhs) => Ok(F32(lhs % rhs as f32)),
188 I64(rhs) => Ok(F32(lhs % rhs as f32)),
189 I128(rhs) => Ok(F32(lhs % rhs as f32)),
190 U8(rhs) => Ok(F32(lhs % f32::from(rhs))),
191 U16(rhs) => Ok(F32(lhs % f32::from(rhs))),
192 U32(rhs) => Ok(F32(lhs % rhs as f32)),
193 U64(rhs) => Ok(F32(lhs % rhs as f32)),
194 U128(rhs) => Ok(F32(lhs % rhs as f32)),
195 F64(rhs) => Ok(F32(lhs % rhs as f32)),
196 F32(rhs) => Ok(F32(lhs % rhs)),
197 Decimal(rhs) => match Decimal::from_f32_retain(lhs) {
198 Some(x) => x.checked_rem(rhs).map_or_else(
199 || {
200 Err(ValueError::BinaryOperationOverflow {
201 lhs: F32(lhs),
202 operator: NumericBinaryOperator::Modulo,
203 rhs: Decimal(rhs),
204 }
205 .into())
206 },
207 |y| Ok(Decimal(y)),
208 ),
209 _ => Err(ValueError::FloatToDecimalConversionFailure(lhs.into()).into()),
210 },
211 Null => Ok(Null),
212 _ => Err(ValueError::NonNumericMathOperation {
213 lhs: F32(lhs),
214 operator: NumericBinaryOperator::Modulo,
215 rhs: rhs.clone(),
216 }
217 .into()),
218 }
219 }
220}
221
222#[cfg(test)]
223mod tests {
224 use {
225 super::{TryBinaryOperator, Value::*},
226 crate::data::{NumericBinaryOperator, ValueError},
227 rust_decimal::prelude::Decimal,
228 std::cmp::Ordering,
229 };
230
231 #[test]
232 fn eq() {
233 let base = 1.0_f32;
234
235 assert_eq!(base, I8(1));
236 assert_eq!(base, I16(1));
237 assert_eq!(base, I32(1));
238 assert_eq!(base, I64(1));
239 assert_eq!(base, I128(1));
240 assert_eq!(base, U8(1));
241 assert_eq!(base, U16(1));
242 assert_eq!(base, U32(1));
243 assert_eq!(base, U64(1));
244 assert_eq!(base, U128(1));
245 assert_eq!(base, F64(1.0));
246 assert_eq!(base, F32(1.0_f32));
247 assert_eq!(base, Decimal(Decimal::from(1)));
248
249 assert_ne!(base, Bool(true));
250 }
251
252 #[test]
253 fn partial_cmp() {
254 let base = 1.0_f32;
255
256 assert_eq!(base.partial_cmp(&I8(1)), Some(Ordering::Equal));
257 assert_eq!(base.partial_cmp(&I16(1)), Some(Ordering::Equal));
258 assert_eq!(base.partial_cmp(&I32(1)), Some(Ordering::Equal));
259 assert_eq!(base.partial_cmp(&I64(1)), Some(Ordering::Equal));
260 assert_eq!(base.partial_cmp(&I128(1)), Some(Ordering::Equal));
261 assert_eq!(base.partial_cmp(&U8(1)), Some(Ordering::Equal));
262 assert_eq!(base.partial_cmp(&U16(1)), Some(Ordering::Equal));
263 assert_eq!(base.partial_cmp(&U32(1)), Some(Ordering::Equal));
264 assert_eq!(base.partial_cmp(&U64(1)), Some(Ordering::Equal));
265 assert_eq!(base.partial_cmp(&U128(1)), Some(Ordering::Equal));
266 assert_eq!(base.partial_cmp(&F64(1.0)), Some(Ordering::Equal));
267 assert_eq!(base.partial_cmp(&F32(1.0_f32)), Some(Ordering::Equal));
268 assert_eq!(
269 base.partial_cmp(&Decimal(Decimal::ONE)),
270 Some(Ordering::Equal)
271 );
272
273 assert_eq!(base.partial_cmp(&Bool(true)), None);
274 }
275
276 #[test]
277 fn try_add() {
278 let base = 1.0_f32;
279
280 assert!(matches!(base.try_add(&I8(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
281 assert!(matches!(base.try_add(&I16(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
282 assert!(matches!(base.try_add(&I32(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
283 assert!(matches!(base.try_add(&I64(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
284 assert!(matches!(base.try_add(&I128(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
285 assert!(matches!(base.try_add(&U8(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
286 assert!(matches!(base.try_add(&U16(1)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
287 assert!(matches!(base.try_add(&U32(1)),Ok(F32(x)) if (x-2.0).abs() < f32::EPSILON));
288 assert!(matches!(base.try_add(&U64(1)),Ok(F32(x)) if (x-2.0).abs() < f32::EPSILON));
289 assert!(matches!(base.try_add(&U128(1)),Ok(F32(x)) if (x-2.0).abs()<f32::EPSILON));
290 assert!(matches!(base.try_add(&F64(1.0)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON ));
291 assert!(
292 matches!(base.try_add(&F32(1.0_f32)), Ok(F32(x)) if (x - 2.0).abs() < f32::EPSILON )
293 );
294 assert!(
295 matches!(base.try_add(&Decimal(Decimal::ONE)), Ok(Decimal(x)) if x == Decimal::TWO)
296 );
297 assert_eq!(
298 f32::MAX.try_add(&Decimal(Decimal::ONE)),
299 Err(ValueError::FloatToDecimalConversionFailure(f32::MAX.into()).into())
300 );
301
302 assert_eq!(
303 base.try_add(&Bool(true)),
304 Err(ValueError::NonNumericMathOperation {
305 lhs: F32(1.0_f32),
306 operator: NumericBinaryOperator::Add,
307 rhs: Bool(true)
308 }
309 .into())
310 );
311 }
312
313 #[test]
314 fn try_subtract() {
315 let base = 1.0_f32;
316
317 assert!(matches!(base.try_subtract(&I8(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
318 assert!(
319 matches!(base.try_subtract(&I16(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
320 );
321 assert!(
322 matches!(base.try_subtract(&I32(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
323 );
324 assert!(
325 matches!(base.try_subtract(&I64(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
326 );
327 assert!(
328 matches!(base.try_subtract(&I128(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
329 );
330 assert!(matches!(base.try_subtract(&U8(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
331 assert!(
332 matches!(base.try_subtract(&U16(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
333 );
334 assert!(
335 matches!(base.try_subtract(&U32(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
336 );
337
338 assert!(
339 matches!(base.try_subtract(&U64(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
340 );
341 assert!(
342 matches!(base.try_subtract(&U128(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
343 );
344
345 assert!(
346 matches!(base.try_subtract(&F64(1.0)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
347 );
348 assert!(
349 matches!(base.try_subtract(&F32(1.0_f32)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
350 );
351 assert!(
352 matches!(base.try_subtract(&Decimal(Decimal::ONE)), Ok(Decimal(x)) if x == Decimal::ZERO)
353 );
354 assert_eq!(
355 f32::MIN.try_subtract(&Decimal(Decimal::ONE)),
356 Err(ValueError::FloatToDecimalConversionFailure(f32::MIN.into()).into())
357 );
358
359 assert_eq!(
360 base.try_subtract(&Bool(true)),
361 Err(ValueError::NonNumericMathOperation {
362 lhs: F32(1.0_f32),
363 operator: NumericBinaryOperator::Subtract,
364 rhs: Bool(true)
365 }
366 .into())
367 );
368 }
369
370 #[test]
371 fn try_multiply() {
372 let base = 1.0_f32;
373
374 assert!(matches!(base.try_multiply(&I8(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
375 assert!(
376 matches!(base.try_multiply(&I16(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
377 );
378 assert!(
379 matches!(base.try_multiply(&I32(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
380 );
381 assert!(
382 matches!(base.try_multiply(&I64(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
383 );
384 assert!(
385 matches!(base.try_multiply(&I128(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
386 );
387 assert!(matches!(base.try_multiply(&U8(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
388 assert!(
389 matches!(base.try_multiply(&U16(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
390 );
391 assert!(
392 matches!(base.try_multiply(&U32(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
393 );
394 assert!(
395 matches!(base.try_multiply(&U64(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
396 );
397 assert!(
398 matches!(base.try_multiply(&U128(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
399 );
400 assert!(
401 matches!(base.try_multiply(&F64(1.0)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
402 );
403 assert!(
404 matches!(base.try_multiply(&F32(1.0_f32)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
405 );
406 assert!(
407 matches!(base.try_multiply(&Decimal(Decimal::ONE)), Ok(Decimal(x)) if x == Decimal::ONE)
408 );
409 assert_eq!(
410 f32::MAX.try_multiply(&Decimal(Decimal::TWO)),
411 Err(ValueError::FloatToDecimalConversionFailure(f32::MAX.into()).into())
412 );
413
414 assert_eq!(
415 base.try_multiply(&Bool(true)),
416 Err(ValueError::NonNumericMathOperation {
417 lhs: F32(1.0_f32),
418 operator: NumericBinaryOperator::Multiply,
419 rhs: Bool(true)
420 }
421 .into())
422 );
423 }
424
425 #[test]
426 fn try_divide() {
427 let base = 1.0_f32;
428
429 assert!(matches!(base.try_divide(&I8(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
430 assert!(matches!(base.try_divide(&I16(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
431 assert!(matches!(base.try_divide(&I32(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
432 assert!(matches!(base.try_divide(&I64(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
433 assert!(matches!(base.try_divide(&I128(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
434 assert!(matches!(base.try_divide(&U8(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
435 assert!(matches!(base.try_divide(&U16(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
436 assert!(matches!(base.try_divide(&U32(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
437 assert!(matches!(base.try_divide(&U64(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
438 assert!(matches!(base.try_divide(&U128(1)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON ));
439
440 assert!(
441 matches!(base.try_divide(&F64(1.0)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
442 );
443 assert!(
444 matches!(base.try_divide(&F32(1.0_f32)), Ok(F32(x)) if (x - 1.0).abs() < f32::EPSILON )
445 );
446 assert!(
447 matches!(2.0_f32.try_divide(&Decimal(Decimal::TWO)), Ok(Decimal(x)) if x == Decimal::ONE)
448 );
449 assert_eq!(
450 f32::MIN.try_divide(&Decimal(Decimal::TWO)),
451 Err(ValueError::FloatToDecimalConversionFailure(f32::MIN.into()).into())
452 );
453
454 assert_eq!(
455 base.try_divide(&Bool(true)),
456 Err(ValueError::NonNumericMathOperation {
457 lhs: F32(1.0_f32),
458 operator: NumericBinaryOperator::Divide,
459 rhs: Bool(true)
460 }
461 .into())
462 );
463 }
464
465 #[test]
466 fn try_modulo() {
467 let base = 1.0_f32;
468
469 assert!(matches!(base.try_modulo(&I8(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
470 assert!(matches!(base.try_modulo(&I16(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
471 assert!(matches!(base.try_modulo(&I32(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
472 assert!(matches!(base.try_modulo(&I64(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
473 assert!(matches!(base.try_modulo(&I128(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
474 assert!(matches!(base.try_modulo(&U8(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
475 assert!(matches!(base.try_modulo(&U16(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
476 assert!(matches!(base.try_modulo(&U32(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
477 assert!(matches!(base.try_modulo(&U64(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
478 assert!(matches!(base.try_modulo(&U128(1)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON ));
479
480 assert!(
481 matches!(base.try_modulo(&F64(1.0)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
482 );
483 assert!(
484 matches!(base.try_modulo(&F32(1.0_f32)), Ok(F32(x)) if (x - 0.0).abs() < f32::EPSILON )
485 );
486 assert!(
487 matches!(base.try_modulo(&Decimal(Decimal::ONE)), Ok(Decimal(x)) if x == Decimal::ZERO)
488 );
489 assert_eq!(
490 f32::MAX.try_modulo(&Decimal(Decimal::TWO)),
491 Err(ValueError::FloatToDecimalConversionFailure(f32::MAX.into()).into())
492 );
493 assert_eq!(
494 base.try_modulo(&Decimal(Decimal::ZERO)),
495 Err(ValueError::BinaryOperationOverflow {
496 lhs: F32(base),
497 rhs: Decimal(Decimal::ZERO),
498 operator: NumericBinaryOperator::Modulo,
499 }
500 .into())
501 );
502
503 assert_eq!(
504 base.try_modulo(&Bool(true)),
505 Err(ValueError::NonNumericMathOperation {
506 lhs: F32(1.0_f32),
507 operator: NumericBinaryOperator::Modulo,
508 rhs: Bool(true)
509 }
510 .into())
511 );
512 }
513}