1use std::ops::{Rem, Add};
2pub trait Mod<RHS=Self> {
13 type Output;
14 #[inline]
15 fn modulo(self, rhs: RHS) -> Self::Output;
16}
17
18impl<A, B, C> Mod<B> for A where A: Rem<B, Output=C>, B: Clone, C: Add<B, Output=C> + Default + PartialOrd {
19 type Output = C;
20 fn modulo(self, rhs: B) -> Self::Output {
21 let result = self % rhs.clone();
22 if result < Self::Output::default() {
23 result + rhs
24 } else {
25 result
26 }
27 }
28}
29
30#[cfg(test)]
31mod test {
32 use super::Mod;
33
34 #[test]
35 fn smaller_than_modulus_works() {
36 assert_eq!(3, 3.modulo(9));
37 assert_eq!(7, 7.modulo(8));
38 }
39
40 #[test]
41 fn larger_than_modulus_works() {
42 assert_eq!(1, 6.modulo(5));
43 assert_eq!(8, 18.modulo(10));
44 }
45
46 #[test]
47 fn megative_works() {
48 assert_eq!(1, (-1).modulo(2));
49 assert_eq!(2, (-7).modulo(3));
50 }
51
52 #[test]
53 fn big_number_works() {
54 assert_eq!(1, 101.modulo(10));
55 }
56}