use crate::Field;
use std::ops::Range;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Separators {
pub field: char,
pub component: char,
pub repeat: char,
pub escape: char,
pub subcomponent: char,
}
impl Default for Separators {
fn default() -> Self {
Separators {
field: '|',
component: '^',
repeat: '~',
escape: '\\',
subcomponent: '&',
}
}
}
impl Separators {
pub fn decode<S: AsRef<str>>(&self, source: S) -> String {
let mut tmp = [0; 4];
source
.as_ref()
.replace(r#"\F\"#, self.field.encode_utf8(&mut tmp))
.replace(r#"\R\"#, self.repeat.encode_utf8(&mut tmp))
.replace(r#"\S\"#, self.component.encode_utf8(&mut tmp))
.replace(r#"\T\"#, self.subcomponent.encode_utf8(&mut tmp))
.replace(r#"\.br\"#, "\r")
.replace(r#"\X0A\"#, "\n")
.replace(r#"\X0D\"#, "\r")
.replace(r#"\E\"#, self.escape.encode_utf8(&mut tmp))
}
pub fn is_special_char(&self, c: char) -> bool {
c == self.field
|| c == self.component
|| c == self.repeat
|| c == self.escape
|| c == self.subcomponent
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct Msh {
pub range: Range<usize>,
pub separators: Separators,
pub fields: Vec<Field>,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn can_decode_encoding_characters() {
let separators = Separators::default();
assert_eq!(separators.decode(r#"\.br\\X0A\\X0D\"#).as_str(), "\r\n\r");
assert_eq!(separators.decode(r#"\F\\R\\S\\T\\E\"#).as_str(), r#"|~^&\"#);
assert_eq!(separators.decode(r#"\E\\F\\E\"#).as_str(), r#"\|\"#);
}
}