eml_nl/utils/
reporting_unit_identifier_id.rs1use std::sync::LazyLock;
2
3use regex::Regex;
4use thiserror::Error;
5
6use crate::{EMLError, EMLValueResultExt, utils::StringValueData};
7
8static REPORTING_UNIT_IDENTIFIER_ID_RE: LazyLock<Regex> = LazyLock::new(|| {
10 Regex::new(r"^((HSB\d+)|((HSB\d+::)?\d{4})|(((HSB\d+::)?\d{4}::)?SB\d+)|(HSB\d+::SB\d+))$")
11 .expect("Failed to compile ReportingUnitIdentifier id regex")
12});
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
16#[repr(transparent)]
17pub struct ReportingUnitIdentifierId(String);
18
19impl ReportingUnitIdentifierId {
20 pub fn new(s: impl AsRef<str>) -> Result<Self, EMLError> {
22 StringValueData::parse_from_str(s.as_ref()).wrap_value_error()
23 }
24
25 pub fn value(&self) -> &str {
27 &self.0
28 }
29}
30
31#[derive(Debug, Clone, Error)]
33#[error("Invalid reporting unit identifier id: {0}")]
34pub struct InvalidReportingUnitIdentifierIdError(String);
35
36impl StringValueData for ReportingUnitIdentifierId {
37 type Error = InvalidReportingUnitIdentifierIdError;
38 fn parse_from_str(s: &str) -> Result<Self, Self::Error>
39 where
40 Self: Sized,
41 {
42 if REPORTING_UNIT_IDENTIFIER_ID_RE.is_match(s) {
43 Ok(ReportingUnitIdentifierId(s.to_string()))
44 } else {
45 Err(InvalidReportingUnitIdentifierIdError(s.to_string()))
46 }
47 }
48
49 fn to_raw_value(&self) -> String {
50 self.0.clone()
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn test_reporting_unit_identifier_id_regex_compiles() {
60 LazyLock::force(&REPORTING_UNIT_IDENTIFIER_ID_RE);
61 }
62
63 #[test]
64 fn test_valid_reporting_unit_identifier_ids() {
65 let valid_ids = [
66 "HSB123",
67 "HSB123::5678",
68 "5678",
69 "SB456",
70 "HSB123::SB456",
71 "HSB123::5678::SB456",
72 ];
73 for id in valid_ids {
74 assert!(
75 ReportingUnitIdentifierId::new(id).is_ok(),
76 "ReportingUnitIdentifierId should accept valid id: {}",
77 id
78 );
79 }
80 }
81
82 #[test]
83 fn test_invalid_reporting_unit_identifier_ids() {
84 let invalid_ids = [
85 "",
86 "HSB",
87 "HSB::123",
88 "HSB123::",
89 "::5678",
90 "HSB123::5678::",
91 "HSB123::5678::SB",
92 ];
93 for id in invalid_ids {
94 assert!(
95 ReportingUnitIdentifierId::new(id).is_err(),
96 "ReportingUnitIdentifierId should reject invalid id: {}",
97 id
98 );
99 }
100 }
101}