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
use std::convert::From;
use std::ops::Deref;

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct U5(u8);

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct U7(u8);

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct U14(u16);

#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct Channel(u8);

impl From<u8> for U7 {
    fn from(i: u8) -> U7 {
        debug_assert!(i & 0x80 == 0);
        U7(i & 0x7f)
    }
}

impl Deref for U7 {
    type Target = u8;

    #[inline]
    fn deref(&self) -> &u8 { &self.0 }
}

impl From<u8> for U5 {
    fn from(i: u8) -> U5 {
        debug_assert!(i & 0xe0 == 0);
        U5(i & 0x1f)
    }
}

impl Deref for U5 {
    type Target = u8;

    #[inline]
    fn deref(&self) -> &u8 { &self.0 }
}

impl From<u16> for U14 {
    fn from(i: u16) -> U14 {
        debug_assert!(i & 0xc000 == 0);
        U14(i & 0x3fff)
    }
}

impl From<(U7, U7)> for U14 {
    fn from(i: (U7, U7)) -> U14 {
        U14(*i.0 as u16 + ((*i.1 as u16) << 7))
    }
}

impl From<U14> for (U7, U7) {
    fn from(i: U14) -> (U7, U7) {
        (i.lsb(), i.msb())
    }
}

impl U14 {
    #[inline]
    pub fn lsb(&self) -> U7 { U7((self.0 & 0x7f) as u8) }
    #[inline]
    pub fn msb(&self) -> U7 { U7((self.0 >> 7) as u8) }
}

impl Deref for U14 {
    type Target = u16;

    #[inline]
    fn deref(&self) -> &u16 { &self.0 }
}

impl From<u8> for Channel {
    fn from(i: u8) -> Channel {
        debug_assert!(i & 0xf0 == 0);
        Channel(i & 0x0f)
    }
}

impl Deref for Channel {
    type Target = u8;

    #[inline]
    fn deref(&self) -> &u8 { &self.0 }
}

#[test]
#[should_panic]
fn out_of_range() {
    let _: U7 = 129.into();
}

#[test]
fn test_u14() {
    let a = U7(0x40);
    let b = U7(0x30);
    let c: U14 = (b, a).into();
    assert_eq!(c.msb(), a);
    assert_eq!(c.lsb(), b);
    assert_eq!(*c, 0x2030);
}