Converts midi channel and cable to be enums.

This will allow pattern matching and seems to
be more use-able.

Tests are defined to ensure the u8 serialization still
corresponds to expected midi values
This commit is contained in:
beau trepp 2019-12-12 19:38:15 +08:00
parent dd37e5efcc
commit a11b695c5e
6 changed files with 133 additions and 15 deletions

View file

@ -21,7 +21,6 @@ impl Into<u8> for CodeIndexNumber {
}
}
impl CodeIndexNumber {
/// Miscellaneous function codes. Reserved for future extensions

View file

@ -2,24 +2,79 @@ use crate::util::try_from::{TryFrom};
/// The MidiChannel is a value ranging from 0x0 to 0xF
/// This is a standard midi concept
pub struct MidiChannel(u8);
#[derive(Debug)]
#[repr(u8)]
pub enum MidiChannel {
Channel0 = 0x0, Channel1 = 0x1, Channel2 = 0x2, Channel3 = 0x3,
Channel4 = 0x4, Channel5 = 0x5, Channel6 = 0x6, Channel7 = 0x7,
Channel8 = 0x8, Channel9 = 0x9, Channel10 = 0xA, Channel11 = 0xB,
Channel12 = 0xC, Channel13 = 0xD, Channel14 = 0xE, Channel15 = 0xF
}
impl TryFrom<u8> for MidiChannel {
fn try_from(value:u8) -> Option<MidiChannel> {
if value > 0xF {
None
} else {
Some(MidiChannel(value))
fn try_from(value:u8) -> Option<Self> {
match value {
x if x == MidiChannel::Channel0 as u8 => Some(MidiChannel::Channel0),
x if x == MidiChannel::Channel1 as u8 => Some(MidiChannel::Channel1),
x if x == MidiChannel::Channel2 as u8 => Some(MidiChannel::Channel2),
x if x == MidiChannel::Channel3 as u8 => Some(MidiChannel::Channel3),
x if x == MidiChannel::Channel4 as u8 => Some(MidiChannel::Channel4),
x if x == MidiChannel::Channel5 as u8 => Some(MidiChannel::Channel5),
x if x == MidiChannel::Channel6 as u8 => Some(MidiChannel::Channel6),
x if x == MidiChannel::Channel7 as u8 => Some(MidiChannel::Channel7),
x if x == MidiChannel::Channel8 as u8 => Some(MidiChannel::Channel8),
x if x == MidiChannel::Channel9 as u8 => Some(MidiChannel::Channel9),
x if x == MidiChannel::Channel10 as u8 => Some(MidiChannel::Channel10),
x if x == MidiChannel::Channel11 as u8 => Some(MidiChannel::Channel11),
x if x == MidiChannel::Channel12 as u8 => Some(MidiChannel::Channel12),
x if x == MidiChannel::Channel13 as u8 => Some(MidiChannel::Channel13),
x if x == MidiChannel::Channel14 as u8 => Some(MidiChannel::Channel14),
x if x == MidiChannel::Channel15 as u8 => Some(MidiChannel::Channel15),
_ => None
}
}
}
impl Into<u8> for MidiChannel {
fn into(self) -> u8 {
self.0
self as u8
}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! channel_test {
($($id:ident:$value:expr,)*) => {
$(
#[test]
fn $id() {
let (input,expected) = $value;
assert_eq!(input as u8, expected);
}
)*
}
}
channel_test! {
cable_0: (MidiChannel::Channel0,0),
cable_1: (MidiChannel::Channel1,1),
cable_2: (MidiChannel::Channel2,2),
cable_3: (MidiChannel::Channel3,3),
cable_4: (MidiChannel::Channel4,4),
cable_5: (MidiChannel::Channel5,5),
cable_6: (MidiChannel::Channel6,6),
cable_7: (MidiChannel::Channel7,7),
cable_8: (MidiChannel::Channel8,8),
cable_9: (MidiChannel::Channel9,9),
cable_10: (MidiChannel::Channel10,10),
cable_11: (MidiChannel::Channel11,11),
cable_12: (MidiChannel::Channel12,12),
cable_13: (MidiChannel::Channel13,13),
cable_14: (MidiChannel::Channel14,14),
cable_15: (MidiChannel::Channel15,15),
}
}

View file

@ -0,0 +1,4 @@
pub struct MidiMessage {
payload: [u8;3]
}

View file

@ -1,3 +1,4 @@
pub mod notes;
pub mod code_index_number;
pub mod midi_channel;
pub mod midi_message;

View file

@ -3,21 +3,79 @@ use crate::util::try_from::{TryFrom};
/// The Cable Number (CN) is a value ranging from 0x0 to 0xF
/// indicating the number assignment of the Embedded MIDI Jack associated
/// with the endpoint that is transferring the data
pub struct CableNumber(u8);
#[derive(Debug)]
#[repr(u8)]
pub enum CableNumber {
Cable0 = 0x0, Cable1 = 0x1, Cable2 = 0x2, Cable3 = 0x3,
Cable4 = 0x4, Cable5 = 0x5, Cable6 = 0x6, Cable7 = 0x7,
Cable8 = 0x8, Cable9 = 0x9, Cable10 = 0xA, Cable11 = 0xB,
Cable12 = 0xC, Cable13 = 0xD, Cable14 = 0xE, Cable15 = 0xF
}
impl TryFrom<u8> for CableNumber {
fn try_from(value:u8) -> Option<Self> {
if value > 0xF {
None
} else {
Some(CableNumber(value))
match value {
x if x == CableNumber::Cable0 as u8 => Some(CableNumber::Cable0),
x if x == CableNumber::Cable1 as u8 => Some(CableNumber::Cable1),
x if x == CableNumber::Cable2 as u8 => Some(CableNumber::Cable2),
x if x == CableNumber::Cable3 as u8 => Some(CableNumber::Cable3),
x if x == CableNumber::Cable4 as u8 => Some(CableNumber::Cable4),
x if x == CableNumber::Cable5 as u8 => Some(CableNumber::Cable5),
x if x == CableNumber::Cable6 as u8 => Some(CableNumber::Cable6),
x if x == CableNumber::Cable7 as u8 => Some(CableNumber::Cable7),
x if x == CableNumber::Cable8 as u8 => Some(CableNumber::Cable8),
x if x == CableNumber::Cable9 as u8 => Some(CableNumber::Cable9),
x if x == CableNumber::Cable10 as u8 => Some(CableNumber::Cable10),
x if x == CableNumber::Cable11 as u8 => Some(CableNumber::Cable11),
x if x == CableNumber::Cable12 as u8 => Some(CableNumber::Cable12),
x if x == CableNumber::Cable13 as u8 => Some(CableNumber::Cable13),
x if x == CableNumber::Cable14 as u8 => Some(CableNumber::Cable14),
x if x == CableNumber::Cable15 as u8 => Some(CableNumber::Cable15),
_ => None
}
}
}
impl Into<u8> for CableNumber {
fn into(self) -> u8 {
self.0
self as u8
}
}
#[cfg(test)]
mod tests {
use super::*;
macro_rules! cable_test {
($($id:ident:$value:expr,)*) => {
$(
#[test]
fn $id() {
let (input,expected) = $value;
assert_eq!(input as u8, expected);
}
)*
}
}
cable_test! {
cable_0: (CableNumber::Cable0,0),
cable_1: (CableNumber::Cable1,1),
cable_2: (CableNumber::Cable2,2),
cable_3: (CableNumber::Cable3,3),
cable_4: (CableNumber::Cable4,4),
cable_5: (CableNumber::Cable5,5),
cable_6: (CableNumber::Cable6,6),
cable_7: (CableNumber::Cable7,7),
cable_8: (CableNumber::Cable8,8),
cable_9: (CableNumber::Cable9,9),
cable_10: (CableNumber::Cable10,10),
cable_11: (CableNumber::Cable11,11),
cable_12: (CableNumber::Cable12,12),
cable_13: (CableNumber::Cable13,13),
cable_14: (CableNumber::Cable14,14),
cable_15: (CableNumber::Cable15,15),
}
}

View file

@ -2,6 +2,7 @@ use crate::data::usb_midi::cable_number::CableNumber;
use crate::data::midi::code_index_number::CodeIndexNumber;
use crate::data::midi::notes::Note;
use crate::data::midi::midi_channel::MidiChannel;
use crate::data::midi::midi_message::MidiMessage;
/// A packet that communicates with the host
/// Note that the payload seems fairly 'open'