stlplus_rs/
util.rs

1use crate::Error;
2use num_traits::{AsPrimitive, Float, Zero};
3use std::ops::Add;
4
5pub trait NextOddInt {
6    fn next_odd(&self) -> Self;
7}
8
9macro_rules! impl_nextoddint {
10    ($($t:ty),*) => {
11        $(
12            impl NextOddInt for $t {
13                fn next_odd(&self) -> Self {
14                    if self % 2 == 0 {
15                        self + 1
16                    } else {
17                        *self
18                    }
19                }
20            }
21        )*
22    };
23}
24impl_nextoddint!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
25
26pub trait NextOdd {
27    fn next_odd(&self) -> i64;
28}
29
30impl<T> NextOdd for T
31where
32    T: Float + 'static + Copy + AsPrimitive<i64>,
33{
34    fn next_odd(&self) -> i64 {
35        let rounded: i64 = self.round().as_();
36        rounded.next_odd()
37    }
38}
39
40pub trait ValidateNotZero {
41    fn validate_not_zero(self) -> Result<Self, Error>
42    where
43        Self: Sized;
44}
45
46impl<T> ValidateNotZero for T
47where
48    T: Zero,
49{
50    fn validate_not_zero(self) -> Result<Self, Error> {
51        if self.is_zero() {
52            Err(Error::UnexpectedZero)
53        } else {
54            Ok(self)
55        }
56    }
57}
58
59pub trait SumAgg {
60    type Output;
61
62    fn sum_agg(&self) -> Self::Output;
63}
64
65impl<T> SumAgg for [T]
66where
67    T: Zero + Copy + Add,
68{
69    type Output = T;
70
71    fn sum_agg(&self) -> Self::Output {
72        self.iter().fold(T::zero(), |a, b| a + *b)
73    }
74}