midi_controller/
routing.rs1use bitflags::bitflags;
7
8bitflags! {
9 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
11 pub struct MidiPort: u8 {
12 const DIN = 0x01;
14 const USB = 0x02;
16 const BLE = 0x04;
18 }
19}
20
21impl MidiPort {
22 pub const ALL: Self = Self::DIN.union(Self::USB);
24}
25
26#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct MidiOut {
29 pub data: [u8; 8],
31 pub len: u8,
33 pub dest: MidiPort,
35}
36
37impl MidiOut {
38 pub fn new(data: &[u8], dest: MidiPort) -> Self {
40 let mut buf = [0u8; 8];
41 let len = data.len().min(8);
42 buf[..len].copy_from_slice(&data[..len]);
43 Self {
44 data: buf,
45 len: len as u8,
46 dest,
47 }
48 }
49
50 pub fn bytes(&self) -> &[u8] {
52 &self.data[..self.len as usize]
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn port_single_bit() {
62 assert_eq!(MidiPort::DIN.bits(), 0x01);
63 assert_eq!(MidiPort::USB.bits(), 0x02);
64 assert_eq!(MidiPort::BLE.bits(), 0x04);
65 }
66
67 #[test]
68 fn port_union() {
69 let both = MidiPort::DIN | MidiPort::USB;
70 assert!(both.contains(MidiPort::DIN));
71 assert!(both.contains(MidiPort::USB));
72 assert!(!both.contains(MidiPort::BLE));
73 }
74
75 #[test]
76 fn port_all_includes_din_and_usb() {
77 assert!(MidiPort::ALL.contains(MidiPort::DIN));
78 assert!(MidiPort::ALL.contains(MidiPort::USB));
79 }
80
81 #[test]
82 fn port_empty() {
83 let empty = MidiPort::empty();
84 assert!(!empty.contains(MidiPort::DIN));
85 assert!(!empty.contains(MidiPort::USB));
86 assert!(empty.is_empty());
87 }
88
89 #[test]
90 fn midi_out_new_3byte() {
91 let msg = MidiOut::new(&[0x90, 60, 127], MidiPort::USB);
92 assert_eq!(msg.len, 3);
93 assert_eq!(msg.bytes(), &[0x90, 60, 127]);
94 assert_eq!(msg.dest, MidiPort::USB);
95 }
96
97 #[test]
98 fn midi_out_new_multi_dest() {
99 let msg = MidiOut::new(&[0xB0, 7, 100], MidiPort::DIN | MidiPort::USB);
100 assert!(msg.dest.contains(MidiPort::DIN));
101 assert!(msg.dest.contains(MidiPort::USB));
102 assert!(!msg.dest.contains(MidiPort::BLE));
103 }
104
105 #[test]
106 fn midi_out_8byte_ump() {
107 let data = [0x40, 0x90, 0x3C, 0x00, 0x7F, 0x00, 0x00, 0x00];
108 let msg = MidiOut::new(&data, MidiPort::ALL);
109 assert_eq!(msg.len, 8);
110 assert_eq!(msg.bytes(), &data);
111 }
112
113 #[test]
114 fn midi_out_truncates_oversize() {
115 let data = [0u8; 16]; let msg = MidiOut::new(&data, MidiPort::DIN);
117 assert_eq!(msg.len, 8); }
119}