Skip to content

Commit ae3e65b

Browse files
committed
Added U14 primitive value type
1 parent 5155ddf commit ae3e65b

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1010
### Added
1111

1212
- `Message` enum variants for *System Common* and *System Realtime* messages.
13+
- `U14` primitive value type.
1314
- Derive `Debug`, `Clone`, `Eq`, and `PartialEq` for `U4`.
1415
- Derive `Debug`, `Clone`, `Eq`, and `PartialEq` for `InvalidU4`.
1516
- Derive `Debug`, `Clone`, `Eq`, and `PartialEq` for `InvalidU7`.

src/message/data/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Primitives and structures used in USB MIDI data.
22
3+
pub mod u14;
34
pub mod u4;
45
pub mod u7;
56

src/message/data/u14.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//! A primitive value with 14-bit length.
2+
3+
use crate::message::data::{FromClamped, FromOverFlow};
4+
5+
/// A primitive value that can be from 0-0x4000
6+
#[derive(Debug, Clone, Eq, PartialEq)]
7+
pub struct U14(u16);
8+
9+
/// Error representing that this value is not a valid u14
10+
#[derive(Debug, Clone, Eq, PartialEq)]
11+
pub struct InvalidU14(pub u16);
12+
13+
impl TryFrom<u16> for U14 {
14+
type Error = InvalidU14;
15+
16+
fn try_from(value: u16) -> Result<Self, Self::Error> {
17+
if value > 0x3FFF {
18+
Err(InvalidU14(value))
19+
} else {
20+
Ok(U14(value))
21+
}
22+
}
23+
}
24+
25+
impl From<U14> for u16 {
26+
fn from(value: U14) -> u16 {
27+
value.0
28+
}
29+
}
30+
31+
impl FromOverFlow<u16> for U14 {
32+
fn from_overflow(value: u16) -> U14 {
33+
const MASK: u16 = 0b0011_1111_1111_1111;
34+
let value = MASK & value;
35+
U14(value)
36+
}
37+
}
38+
39+
impl FromClamped<u16> for U14 {
40+
fn from_clamped(value: u16) -> U14 {
41+
match U14::try_from(value) {
42+
Ok(x) => x,
43+
_ => U14::MAX,
44+
}
45+
}
46+
}
47+
48+
impl U14 {
49+
/// Maximum value for the type.
50+
pub const MAX: U14 = U14(0x3FFF);
51+
/// Minimum value for the type.
52+
pub const MIN: U14 = U14(0);
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use super::*;
58+
59+
#[test]
60+
fn try_from_valid() {
61+
assert_eq!(U14::try_from(0x1234), Ok(U14(0x1234)));
62+
}
63+
64+
#[test]
65+
fn try_from_invalid() {
66+
assert_eq!(U14::try_from(0x4000), Err(InvalidU14(0x4000)));
67+
}
68+
69+
#[test]
70+
fn from_overflow() {
71+
assert_eq!(U14::from_overflow(0x400F), U14(0x0F));
72+
}
73+
74+
#[test]
75+
fn from_clamped() {
76+
assert_eq!(U14::from_clamped(0x400F), U14(0x3FFF));
77+
}
78+
}

0 commit comments

Comments
 (0)