1use super::Measure;
2use std::ops::Mul;
3
4#[derive(Debug)]
5pub enum Unit {
6 MY,
8 MM,
10 CM,
12 INCH,
14 FT,
16 YD,
18 METER,
20 KM,
22 MILE,
24 DYN(usize),
26}
27
28impl Unit {
29 #[inline]
30 pub fn multiply(&self) -> i64 {
31 use Unit::*;
32 match self {
33 MY => Measure::MY,
34 MM => Measure::MY * 1_000,
35 CM => Measure::MY * 10_000,
36 INCH => Measure::MY * 25_400,
37 FT => Measure::MY * 304_800,
38 YD => Measure::MY * 914_400,
39 METER => Measure::MY * 1_000_000,
40 KM => Measure::MY * 1_000_000_000,
41 MILE => Measure::MY * 1_609_344_000,
42 DYN(p) => (0..*p).fold(1i64, |acc, _| acc * 10),
43 }
44 }
45}
46
47impl PartialEq for Unit {
48 fn eq(&self, other: &Self) -> bool {
49 self.multiply() == other.multiply()
50 }
51}
52
53macro_rules! unit_from_number {
54 ($($typ:ident),+) => {
55 $(
56 impl Mul<$typ> for Unit {
57 type Output = Measure;
58
59 fn mul(self, rhs: $typ) -> Self::Output {
60 Measure::from(self.multiply() * rhs as i64)
61 }
62 }
63
64 impl Mul<Unit> for $typ {
65 type Output = Measure;
66
67 fn mul(self, rhs: Unit) -> Self::Output {
68 Measure::from(rhs.multiply() * self as i64)
69 }
70 }
71 )+
72 }
73}
74
75unit_from_number!(i8, i16, i32, i64, u8, u16, u32, u64);
76
77#[cfg(test)]
78mod should {
79 use crate::{Measure, Unit};
80
81 #[test]
82 fn multiply_with_number() {
83 assert_eq!(Measure::from(3.0), 3 * Unit::MM);
84 assert_eq!(Measure::from(55000.0), 55 * Unit::METER);
85 }
86
87 #[test]
88 fn be_equal_dyn() {
89 assert_eq!(Unit::MY.multiply(), Unit::DYN(1).multiply());
90 assert_eq!(Unit::MM.multiply(), Unit::DYN(4).multiply());
91 assert_eq!(Unit::METER, Unit::DYN(7));
92 }
93}