1use super::*;
2use std::fmt::Display;
3use std::str::FromStr;
4
5#[derive(Debug, PartialEq, Clone, Copy)]
9pub struct Separators {
10 pub segment: char,
12 pub field: char,
13 pub repeat: char,
14 pub component: char,
15 pub subcomponent: char,
16
17 pub escape_char: char,
18}
19
20impl Separators {
21 pub fn default() -> Separators {
23 Separators {
24 segment: '\r',
25 field: '|',
26 repeat: '~',
27 component: '^',
28 subcomponent: '&',
29 escape_char: '\\',
30 }
31 }
32
33 fn new(message: &str) -> Result<Separators, Hl7ParseError> {
36 let mut chars = message.char_indices();
38
39 if Some((0, 'M')) != chars.next()
40 || Some((1, 'S')) != chars.next()
41 || Some((2, 'H')) != chars.next()
42 {
43 return Err(Hl7ParseError::Msh1Msh2(
44 "Message doesn't start with 'MSH'".to_string(),
45 ));
46 }
47
48 Ok(Separators {
49 segment: '\r',
50 field: chars.next().unwrap().1,
51 component: chars.next().unwrap().1,
52 repeat: chars.next().unwrap().1,
53 escape_char: chars.next().unwrap().1,
54 subcomponent: chars.next().unwrap().1,
55 })
56 }
57}
58
59impl Display for Separators {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(
63 f,
64 "{}{}{}{}",
65 self.component, self.repeat, self.escape_char, self.subcomponent
66 )
67 }
68}
69
70impl FromStr for Separators {
73 type Err = Hl7ParseError;
74
75 fn from_str(input: &str) -> Result<Self, Self::Err> {
76 Separators::new(input)
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::separators::Separators;
83 use super::*;
84
85 #[test]
86 fn ensure_separators_load_correctly() -> Result<(), Hl7ParseError> {
87 let expected = Separators::default();
88 let actual = Separators::new("MSH|^~\\&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3\rMSA|AA|MSGID12349876")?;
89
90 assert_eq!(expected.component, actual.component);
91 assert_eq!(expected.escape_char, actual.escape_char);
92 assert_eq!(expected.field, actual.field);
93 assert_eq!(expected.repeat, actual.repeat);
94 assert_eq!(expected.segment, actual.segment);
95 assert_eq!(expected.subcomponent, actual.subcomponent);
96
97 Ok(())
98 }
99
100 #[test]
101 fn ensure_separators_load_from_string() -> Result<(), Hl7ParseError> {
102 let expected = Separators::default();
103 let actual = str::parse::<Separators>("MSH|^~\\&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3\rMSA|AA|MSGID12349876")?;
104
105 assert_eq!(expected.component, actual.component);
106 assert_eq!(expected.escape_char, actual.escape_char);
107 assert_eq!(expected.field, actual.field);
108 assert_eq!(expected.repeat, actual.repeat);
109 assert_eq!(expected.segment, actual.segment);
110 assert_eq!(expected.subcomponent, actual.subcomponent);
111
112 Ok(())
113 }
114
115 #[test]
116 fn ensure_missing_msh_causes_error() {
117 let result = Separators::new("SH|^~\\&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3\rMSA|AA|MSGID12349876");
119 assert!(result.is_err());
120 }
121
122 #[test]
123 fn ensure_separators_to_string() {
124 assert_eq!("^~\\&", Separators::default().to_string());
125 }
126}