stlplus-rs 0.1.3

Port of the enhanced Seasonal Trend Decomposition using Loess (STL) implementation to rust
Documentation
use crate::Error;
use num_traits::{AsPrimitive, Float, Zero};
use std::ops::Add;

pub trait NextOddInt {
    fn next_odd(&self) -> Self;
}

macro_rules! impl_nextoddint {
    ($($t:ty),*) => {
        $(
            impl NextOddInt for $t {
                fn next_odd(&self) -> Self {
                    if self % 2 == 0 {
                        self + 1
                    } else {
                        *self
                    }
                }
            }
        )*
    };
}
impl_nextoddint!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);

pub trait NextOdd {
    fn next_odd(&self) -> i64;
}

impl<T> NextOdd for T
where
    T: Float + 'static + Copy + AsPrimitive<i64>,
{
    fn next_odd(&self) -> i64 {
        let rounded: i64 = self.round().as_();
        rounded.next_odd()
    }
}

pub trait ValidateNotZero {
    fn validate_not_zero(self) -> Result<Self, Error>
    where
        Self: Sized;
}

impl<T> ValidateNotZero for T
where
    T: Zero,
{
    fn validate_not_zero(self) -> Result<Self, Error> {
        if self.is_zero() {
            Err(Error::UnexpectedZero)
        } else {
            Ok(self)
        }
    }
}

pub trait SumAgg {
    type Output;

    fn sum_agg(&self) -> Self::Output;
}

impl<T> SumAgg for [T]
where
    T: Zero + Copy + Add,
{
    type Output = T;

    fn sum_agg(&self) -> Self::Output {
        self.iter().fold(T::zero(), |a, b| a + *b)
    }
}