usbd_midi/message/data/
u4.rs1use crate::message::data::{FromClamped, FromOverFlow};
4
5#[derive(Debug, Clone, Eq, PartialEq)]
7pub struct U4(u8);
8
9#[derive(Debug, Clone, Eq, PartialEq)]
11pub struct InvalidU4(pub u8);
12
13impl TryFrom<u8> for U4 {
14 type Error = InvalidU4;
15
16 fn try_from(value: u8) -> Result<Self, Self::Error> {
17 if value > U4::MAX.0 {
18 Err(InvalidU4(value))
19 } else {
20 Ok(U4(value))
21 }
22 }
23}
24
25impl From<U4> for u8 {
26 fn from(value: U4) -> u8 {
27 value.0
28 }
29}
30
31impl FromOverFlow<u8> for U4 {
32 fn from_overflow(value: u8) -> U4 {
33 const MASK: u8 = 0b0000_1111;
34 let value = MASK & value;
35 U4(value)
36 }
37}
38
39impl FromClamped<u8> for U4 {
40 fn from_clamped(value: u8) -> U4 {
41 match U4::try_from(value) {
42 Ok(x) => x,
43 _ => U4::MAX,
44 }
45 }
46}
47
48impl U4 {
49 pub const MAX: U4 = U4(0x0F);
51 pub const MIN: U4 = U4(0);
53
54 pub fn combine(upper: U4, lower: U4) -> u8 {
57 let upper = upper.0.overflowing_shl(8).0;
58 let lower = lower.0 & U4::MAX.0;
59 upper | lower
60 }
61
62 pub fn from_overflowing_u8(value: u8) -> U4 {
65 const MASK: u8 = 0b0000_1111;
66 let number = MASK & value;
67 U4(number)
68 }
69}