eryon_core/ops/
modulo.rs

1/*
2    Appellation: modulo <module>
3    Contrib: @FL03
4*/
5
6/// A trait for modular arithmetic; the algorithm is based on the Python `%` operator which
7/// uses the sign of the denominator rather than the numerator.
8pub trait PyMod<Rhs> {
9    type Output;
10
11    fn pymod(self, rhs: Rhs) -> Self::Output;
12}
13
14impl<A, B, C> PyMod<B> for A
15where
16    A: core::ops::Rem<B, Output = C>,
17    B: Copy + num::Zero + PartialOrd,
18    C: core::ops::Add<B, Output = C> + num::Zero + PartialOrd,
19{
20    type Output = C;
21
22    fn pymod(self, rhs: B) -> Self::Output {
23        let r = self % rhs;
24        if (r < C::zero() && rhs > B::zero()) || (r > C::zero() && rhs < B::zero()) {
25            r + rhs
26        } else {
27            r
28        }
29    }
30}