midi2 0.11.1

Ergonomic, versatile, strong types wrapping MIDI 2.0 message data.
Documentation
use ux::{u14, u21, u28, u7};

pub trait Byte: Copy {
    fn to_u8(self) -> u8;
    fn from_u8(v: u8) -> Self;
}

impl Byte for u7 {
    fn to_u8(self) -> u8 {
        self.into()
    }
    fn from_u8(v: u8) -> Self {
        u7::new(v & 0x7F)
    }
}

impl Byte for u8 {
    fn from_u8(v: u8) -> Self {
        v & 0x7F
    }
    fn to_u8(self) -> u8 {
        self & 0x7F
    }
}

pub trait Encode7Bit {
    fn from_u7s<T: Byte>(u7s: &[T]) -> Self;
    fn to_u7s<T: Byte>(&self, data: &mut [T]);
}

impl Encode7Bit for u28 {
    fn to_u7s<T: Byte>(&self, data: &mut [T]) {
        debug_assert!(data.len() == 4);

        let v = u32::from(*self);

        data[0] = T::from_u8(v as u8);
        data[1] = T::from_u8((v >> 7) as u8);
        data[2] = T::from_u8((v >> (7 * 2)) as u8);
        data[3] = T::from_u8((v >> (7 * 3)) as u8);
    }
    fn from_u7s<T: Byte>(u7s: &[T]) -> Self {
        debug_assert!(u7s.len() == 4);

        let mut ret: u28 = Default::default();

        ret |= u28::from(u7s[0].to_u8() & 0x7F);
        ret |= u28::from(u7s[1].to_u8() & 0x7F) << 7;
        ret |= u28::from(u7s[2].to_u8() & 0x7F) << (7 * 2);
        ret |= u28::from(u7s[3].to_u8() & 0x7F) << (7 * 3);

        ret
    }
}

impl Encode7Bit for u21 {
    fn to_u7s<T: Byte>(&self, data: &mut [T]) {
        debug_assert!(data.len() == 3);

        let v = u32::from(*self);

        data[0] = T::from_u8(v as u8);
        data[1] = T::from_u8((v >> 7) as u8);
        data[2] = T::from_u8((v >> (7 * 2)) as u8);
    }
    fn from_u7s<T: Byte>(u7s: &[T]) -> Self {
        debug_assert!(u7s.len() == 3);

        let mut ret: u21 = Default::default();

        ret |= u21::from(u7s[0].to_u8() & 0x7F);
        ret |= u21::from(u7s[1].to_u8() & 0x7F) << 7;
        ret |= u21::from(u7s[2].to_u8() & 0x7F) << (7 * 2);

        ret
    }
}

impl Encode7Bit for u14 {
    fn to_u7s<T: Byte>(&self, data: &mut [T]) {
        debug_assert!(data.len() == 2);

        let v = u16::from(*self);

        data[0] = T::from_u8(v as u8);
        data[1] = T::from_u8((v >> 7) as u8);
    }
    fn from_u7s<T: Byte>(u7s: &[T]) -> Self {
        debug_assert!(u7s.len() == 2);

        let mut ret: u14 = Default::default();

        ret |= u14::from(u7s[0].to_u8() & 0x7F);
        ret |= u14::from(u7s[1].to_u8() & 0x7F) << 7;

        ret
    }
}