1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::ops::{Div, Mul};

use crate::{Unit, Quantity};
use crate::Measure;

/// Measurement conversion from some unit.
///
///
///
///
pub trait FromUnit<N, U: Unit>
{
    type Output;
    fn from_unit(num: N) -> Self::Output;
}

impl<NSelf, MSelf> Measure<NSelf, MSelf> {
    pub fn from_unit<NFrom, UFrom>(from: Measure<NFrom, UFrom>) -> Self
        where
            MSelf: FromUnit<NFrom, UFrom, Output = NSelf>,
            UFrom: Unit,
    {
        Self::new(MSelf::from_unit(from.num))
    }

    pub fn unit_into<NInto, UInto>(self) -> Measure<NInto, UInto>
        where
            MSelf: Unit,
            UInto: Unit + FromUnit<NSelf, MSelf, Output = NInto>,
    {
        Measure::new(UInto::from_unit(self.num))
    }
}

/// Measurement conversion from some quantity.
///
///
///
///
///
pub trait FromQuantity<N, Q: Quantity>
{
    type Output;
    fn from_quantity(num: N) -> Self::Output;
}

///
///
///
///
///
///
pub trait IntoMeasure {
    type Num;
    type Unit : Unit;
    fn into_measure(self) -> Measure<Self::Num, Self::Unit>  where Self: Sized;
}

impl <N, U: Unit> IntoMeasure for Measure<N, U>{
    type Num = N;
    type Unit = U;

    fn into_measure(self) -> Measure<Self::Num, Self::Unit> where Self: Sized {
        Measure::new(self.num)
    }
}

macro_rules! impl_into_measure{
    ( $( $type:ty ,)+ ) => {
        $(
        impl IntoMeasure for $type{
            type Num = $type;
            type Unit = ();
            fn into_measure(self) -> Measure<Self::Num, Self::Unit> where Self: Sized {
                Measure::new(self)
            }
        }
        )+
    };
}

impl_into_measure!{
    i8, i16, i32, i64, i128, isize,
    u8, u16, u32, u64, u128, usize,
             f32, f64,
}

///
///
///
///
///
///
pub trait MulMeasure<URhs: Unit, NSelf, NRhs = NSelf>
where
    Self: Unit,
    NSelf: Mul<NRhs>,
{
    type Output: Unit;
    fn mul_measure(num: NSelf, rhs: NRhs) -> <NSelf as Mul<NRhs>>::Output {
        num * rhs
    }
}

impl<USelf : Unit, NSelf: Mul<NRhs>, NRhs> MulMeasure<(), NSelf, NRhs> for USelf{
    type Output = USelf;
}

///
///
///
///
///
///
pub trait DivMeasure<URhs: Unit, NSelf, NRhs = NSelf>
where
    Self: Unit,
    NSelf: Div<NRhs>,
{
    type Output: Unit;
    fn div_unit(num: NSelf, rhs: NRhs) -> <NSelf as Div<NRhs>>::Output {
        num / rhs
    }
}


impl<USelf : Unit, NSelf: Div<NRhs>, NRhs> DivMeasure<(), NSelf, NRhs> for USelf{
    type Output = USelf;
}