musicxml/datatypes/
ending_number.rs1use alloc::{string::String, string::ToString, vec::Vec};
2use core::ops::Deref;
3use musicxml_internal::{DatatypeDeserializer, DatatypeSerializer};
4use musicxml_macros::DatatypeSerialize;
5use regex::Regex;
6
7#[derive(Debug, PartialEq, Eq, DatatypeSerialize)]
15pub struct EndingNumber(pub String);
16
17impl Deref for EndingNumber {
18 type Target = String;
19 fn deref(&self) -> &Self::Target {
20 &self.0
21 }
22}
23
24impl DatatypeDeserializer for EndingNumber {
25 fn deserialize(value: &str) -> Result<Self, String> {
26 let space_regex = Regex::new(r"^[ ]*$").unwrap();
27 let integer_regex = Regex::new(r"^[1-9][0-9]*(, ?[1-9][0-9]*)*$").unwrap();
28 if space_regex.is_match(value) {
29 Ok(EndingNumber(String::from(value)))
30 } else if integer_regex.is_match(value) {
31 Ok(EndingNumber(value.split(' ').collect::<Vec<_>>().join("")))
32 } else {
33 Err(format!("Value {value} is invalid for the <ending-number> data type"))
34 }
35 }
36}
37
38#[cfg(test)]
39mod ending_number_tests {
40 use super::*;
41
42 #[test]
43 fn deserialize_valid1() {
44 let result = EndingNumber::deserialize("1");
45 assert!(result.is_ok());
46 assert_eq!(result.unwrap(), EndingNumber(String::from("1")));
47 }
48
49 #[test]
50 fn deserialize_valid2() {
51 let result = EndingNumber::deserialize("33");
52 assert!(result.is_ok());
53 assert_eq!(result.unwrap(), EndingNumber(String::from("33")));
54 }
55
56 #[test]
57 fn deserialize_valid3() {
58 let result = EndingNumber::deserialize("348,21");
59 assert!(result.is_ok());
60 assert_eq!(result.unwrap(), EndingNumber(String::from("348,21")));
61 }
62
63 #[test]
64 fn deserialize_valid4() {
65 let result = EndingNumber::deserialize("9, 23, 34,34");
66 assert!(result.is_ok());
67 assert_eq!(result.unwrap(), EndingNumber(String::from("9,23,34,34")));
68 }
69
70 #[test]
71 fn deserialize_invalid1() {
72 let result = EndingNumber::deserialize("02");
73 assert!(result.is_err());
74 }
75
76 #[test]
77 fn deserialize_invalid2() {
78 let result = EndingNumber::deserialize("4,");
79 assert!(result.is_err());
80 }
81
82 #[test]
83 fn deserialize_invalid3() {
84 let result = EndingNumber::deserialize("a");
85 assert!(result.is_err());
86 }
87
88 #[test]
89 fn deserialize_invalid4() {
90 let result = EndingNumber::deserialize(",33");
91 assert!(result.is_err());
92 }
93
94 #[test]
95 fn deserialize_invalid5() {
96 let result = EndingNumber::deserialize("23,33, 2");
97 assert!(result.is_err());
98 }
99}