|
4 | 4 | use vortex_dtype::NativePType; |
5 | 5 | use vortex_vector::primitive::PScalar; |
6 | 6 |
|
7 | | -use crate::arithmetic::{Arithmetic, Operator}; |
| 7 | +use crate::arithmetic::{Arithmetic, CheckedArithmetic, CheckedOperator, Operator}; |
8 | 8 |
|
9 | 9 | impl<Op, T> Arithmetic<Op> for &PScalar<T> |
10 | 10 | where |
11 | 11 | T: NativePType, |
12 | 12 | Op: Operator<T>, |
13 | | - for<'a> &'a T: Arithmetic<Op, &'a T, Output = T>, |
14 | 13 | { |
15 | 14 | type Output = PScalar<T>; |
16 | 15 |
|
17 | 16 | fn eval(self, rhs: &PScalar<T>) -> Self::Output { |
18 | 17 | match (self.value(), rhs.value()) { |
19 | 18 | (Some(a), Some(b)) => { |
20 | | - let value = Arithmetic::<Op, _>::eval(a, b); |
| 19 | + let value = Op::apply(&a, &b); |
21 | 20 | PScalar::new(Some(value)) |
22 | 21 | } |
23 | 22 | (..) => { |
|
27 | 26 | } |
28 | 27 | } |
29 | 28 | } |
| 29 | + |
| 30 | +impl<Op, T> CheckedArithmetic<Op> for &PScalar<T> |
| 31 | +where |
| 32 | + T: NativePType, |
| 33 | + Op: CheckedOperator<T>, |
| 34 | +{ |
| 35 | + type Output = PScalar<T>; |
| 36 | + |
| 37 | + fn checked_eval(self, rhs: Self) -> Option<Self::Output> { |
| 38 | + match (self.value(), rhs.value()) { |
| 39 | + (Some(a), Some(b)) => { |
| 40 | + let value = Op::apply(&a, &b)?; |
| 41 | + Some(PScalar::new(Some(value))) |
| 42 | + } |
| 43 | + (..) => { |
| 44 | + // At least one side is null, so result is null |
| 45 | + Some(PScalar::new(None)) |
| 46 | + } |
| 47 | + } |
| 48 | + } |
| 49 | +} |
| 50 | + |
| 51 | +#[cfg(test)] |
| 52 | +mod test { |
| 53 | + use vortex_vector::primitive::PScalar; |
| 54 | + |
| 55 | + use super::*; |
| 56 | + use crate::arithmetic::{Add, CheckedArithmetic, WrappingSub}; |
| 57 | + |
| 58 | + #[test] |
| 59 | + fn test_add() { |
| 60 | + let left = PScalar::new(Some(5u32)); |
| 61 | + let right = PScalar::new(Some(3u32)); |
| 62 | + |
| 63 | + let result = CheckedArithmetic::<Add>::checked_eval(&left, &right).unwrap(); |
| 64 | + assert_eq!(result.value(), Some(8u32)); |
| 65 | + |
| 66 | + let left_null = PScalar::new(None); |
| 67 | + let result_null = CheckedArithmetic::<Add>::checked_eval(&left_null, &right).unwrap(); |
| 68 | + assert_eq!(result_null.value(), None); |
| 69 | + } |
| 70 | + |
| 71 | + #[test] |
| 72 | + fn test_subtract() { |
| 73 | + let left = PScalar::new(Some(10u32)); |
| 74 | + let right = PScalar::new(Some(4u32)); |
| 75 | + |
| 76 | + let result = Arithmetic::<WrappingSub>::eval(&left, &right); |
| 77 | + assert_eq!(result.value(), Some(6u32)); |
| 78 | + |
| 79 | + let right_null = PScalar::new(None); |
| 80 | + let result_null = Arithmetic::<WrappingSub>::eval(&left, &right_null); |
| 81 | + assert_eq!(result_null.value(), None); |
| 82 | + } |
| 83 | +} |
0 commit comments