use super::*;
use std::fmt::Display;
use std::str::FromStr;
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Separators {
pub segment: char,
pub field: char,
pub repeat: char,
pub component: char,
pub subcomponent: char,
pub escape_char: char,
}
impl Separators {
pub fn default() -> Separators {
Separators {
segment: '\r',
field: '|',
repeat: '~',
component: '^',
subcomponent: '&',
escape_char: '\\',
}
}
fn new(message: &str) -> Result<Separators, Hl7ParseError> {
let mut chars = message.char_indices();
if Some((0, 'M')) != chars.next()
|| Some((1, 'S')) != chars.next()
|| Some((2, 'H')) != chars.next()
{
return Err(Hl7ParseError::Msh1Msh2(
"Message doesn't start with 'MSH'".to_string(),
));
}
Ok(Separators {
segment: '\r',
field: chars.next().unwrap().1,
component: chars.next().unwrap().1,
repeat: chars.next().unwrap().1,
escape_char: chars.next().unwrap().1,
subcomponent: chars.next().unwrap().1,
})
}
}
impl Display for Separators {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}{}{}{}",
self.component, self.repeat, self.escape_char, self.subcomponent
)
}
}
impl FromStr for Separators {
type Err = Hl7ParseError;
fn from_str(input: &str) -> Result<Self, Self::Err> {
Separators::new(input)
}
}
#[cfg(test)]
mod tests {
use super::separators::Separators;
use super::*;
#[test]
fn ensure_separators_load_correctly() -> Result<(), Hl7ParseError> {
let expected = Separators::default();
let actual = Separators::new("MSH|^~\\&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3\rMSA|AA|MSGID12349876")?;
assert_eq!(expected.component, actual.component);
assert_eq!(expected.escape_char, actual.escape_char);
assert_eq!(expected.field, actual.field);
assert_eq!(expected.repeat, actual.repeat);
assert_eq!(expected.segment, actual.segment);
assert_eq!(expected.subcomponent, actual.subcomponent);
Ok(())
}
#[test]
fn ensure_separators_load_from_string() -> Result<(), Hl7ParseError> {
let expected = Separators::default();
let actual = str::parse::<Separators>("MSH|^~\\&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3\rMSA|AA|MSGID12349876")?;
assert_eq!(expected.component, actual.component);
assert_eq!(expected.escape_char, actual.escape_char);
assert_eq!(expected.field, actual.field);
assert_eq!(expected.repeat, actual.repeat);
assert_eq!(expected.segment, actual.segment);
assert_eq!(expected.subcomponent, actual.subcomponent);
Ok(())
}
#[test]
fn ensure_missing_msh_causes_error() {
let result = Separators::new("SH|^~\\&|CATH|StJohn|AcmeHIS|StJohn|20061019172719||ACK^O01|MSGID12349876|P|2.3\rMSA|AA|MSGID12349876");
assert!(result.is_err());
}
#[test]
fn ensure_separators_to_string() {
assert_eq!("^~\\&", Separators::default().to_string());
}
}