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}