musicxml/datatypes/
numeral_value.rs

1use alloc::string::{String, ToString};
2use core::ops::Deref;
3use musicxml_internal::{DatatypeDeserializer, DatatypeSerializer};
4use musicxml_macros::DatatypeSerialize;
5
6/// Represents a Roman numeral or Nashville number value as a positive integer from 1 to 7.
7///
8/// The value of an instance of this type may be accessed by dereferencing the struct: `*datatype_val`.
9///
10/// **Minimum value**: 1
11///
12/// **Maximum value**: 7
13#[derive(Debug, PartialEq, Eq, DatatypeSerialize)]
14pub struct NumeralValue(pub u8);
15
16impl Deref for NumeralValue {
17  type Target = u8;
18  fn deref(&self) -> &Self::Target {
19    &self.0
20  }
21}
22
23impl DatatypeDeserializer for NumeralValue {
24  fn deserialize(value: &str) -> Result<Self, String> {
25    match value.parse::<u8>() {
26      Ok(val) => match val {
27        1..=7 => Ok(NumeralValue(val)),
28        _ => Err(format!("Value {val} is invalid for the <numeral-value> data type")),
29      },
30      Err(_) => Err(format!("Invalid value {value} for <numeral-value>")),
31    }
32  }
33}
34
35#[cfg(test)]
36mod numeral_value_tests {
37  use super::*;
38
39  #[test]
40  fn deserialize_valid1() {
41    let result = NumeralValue::deserialize("1");
42    assert!(result.is_ok());
43    assert_eq!(result.unwrap(), NumeralValue(1));
44  }
45
46  #[test]
47  fn deserialize_valid2() {
48    let result = NumeralValue::deserialize("7");
49    assert!(result.is_ok());
50    assert_eq!(result.unwrap(), NumeralValue(7));
51  }
52
53  #[test]
54  fn deserialize_invalid1() {
55    let result = NumeralValue::deserialize("0");
56    assert!(result.is_err());
57  }
58
59  #[test]
60  fn deserialize_invalid2() {
61    let result = NumeralValue::deserialize("8");
62    assert!(result.is_err());
63  }
64
65  #[test]
66  fn deserialize_invalid3() {
67    let result = NumeralValue::deserialize("-2");
68    assert!(result.is_err());
69  }
70}