use crate::{
EMLError, NS_XAL,
io::{EMLElement, EMLElementReader, EMLElementWriter, QualifiedName, collect_struct},
};
#[derive(Debug, Clone)]
pub struct PostalCode {
pub number: PostalCodeNumber,
pub postal_code_type: Option<String>,
}
impl PostalCode {
pub fn new(number: impl Into<String>) -> Self {
PostalCode {
number: PostalCodeNumber {
number_type: None,
code: None,
number: number.into(),
},
postal_code_type: None,
}
}
pub fn number(&self) -> &str {
&self.number.number
}
pub fn with_type(mut self, postal_code_type: impl Into<String>) -> Self {
self.postal_code_type = Some(postal_code_type.into());
self
}
pub fn with_number_type(mut self, number_type: impl Into<String>) -> Self {
self.number.number_type = Some(number_type.into());
self
}
pub fn with_number_code(mut self, code: impl Into<String>) -> Self {
self.number.code = Some(code.into());
self
}
}
impl From<String> for PostalCode {
fn from(number: String) -> Self {
PostalCode::new(number)
}
}
impl From<&str> for PostalCode {
fn from(number: &str) -> Self {
PostalCode::new(number)
}
}
impl EMLElement for PostalCode {
const EML_NAME: QualifiedName<'_, '_> = QualifiedName::from_static("PostalCode", Some(NS_XAL));
fn read_eml(elem: &mut EMLElementReader<'_, '_>) -> Result<Self, EMLError> {
Ok(collect_struct!(elem, PostalCode {
number: PostalCodeNumber::EML_NAME => |elem| PostalCodeNumber::read_eml(elem)?,
postal_code_type: elem.attribute_value("Type")?.map(|s| s.into_owned()),
}))
}
fn write_eml(&self, writer: EMLElementWriter) -> Result<(), EMLError> {
writer
.attr_opt("Type", self.postal_code_type.as_ref())?
.child_elem(PostalCodeNumber::EML_NAME, &self.number)?
.finish()
}
}
#[derive(Debug, Clone)]
pub struct PostalCodeNumber {
pub number_type: Option<String>,
pub code: Option<String>,
pub number: String,
}
impl EMLElement for PostalCodeNumber {
const EML_NAME: QualifiedName<'_, '_> =
QualifiedName::from_static("PostalCodeNumber", Some(NS_XAL));
fn read_eml(elem: &mut EMLElementReader<'_, '_>) -> Result<Self, EMLError> {
let number_type = elem.attribute_value("Type")?.map(|s| s.into_owned());
let code = elem.attribute_value("Code")?.map(|s| s.into_owned());
let number = elem.text_without_children()?;
Ok(PostalCodeNumber {
number_type,
code,
number,
})
}
fn write_eml(&self, mut writer: EMLElementWriter) -> Result<(), EMLError> {
if let Some(number_type) = &self.number_type {
writer = writer.attr("Type", number_type.as_ref())?
}
if let Some(code) = &self.code {
writer = writer.attr("Code", code.as_ref())?
}
writer.text(self.number.as_ref())?.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::io::{EMLParsingMode, EMLRead, test_write_eml_element, test_xml_fragment};
#[test]
fn test_postal_code_construction() {
let postal_code = PostalCode::new("1234 AB")
.with_type("Test")
.with_number_type("Primary")
.with_number_code("PC123");
assert_eq!(postal_code.number(), "1234 AB");
assert_eq!(postal_code.postal_code_type.as_deref(), Some("Test"));
assert_eq!(postal_code.number.number_type.as_deref(), Some("Primary"));
assert_eq!(postal_code.number.code.as_deref(), Some("PC123"));
}
#[test]
fn test_postal_code_parsing() {
let xml = test_xml_fragment(
r#"
<xal:PostalCode xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0" Type="Test">
<xal:PostalCodeNumber Type="Primary" Code="PC123">1234 AB</xal:PostalCodeNumber>
</xal:PostalCode>
"#,
);
let postal_code = PostalCode::parse_eml(&xml, EMLParsingMode::Strict).unwrap();
assert_eq!(postal_code.number(), "1234 AB");
assert_eq!(postal_code.postal_code_type.as_deref(), Some("Test"));
assert_eq!(postal_code.number.number_type.as_deref(), Some("Primary"));
assert_eq!(postal_code.number.code.as_deref(), Some("PC123"));
let xml_output = test_write_eml_element(&postal_code, &[NS_XAL]).unwrap();
assert_eq!(xml_output, xml);
}
#[test]
fn test_postal_code_simple_parsing() {
let xml = test_xml_fragment(
r#"
<xal:PostalCode xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<xal:PostalCodeNumber>1234 AB</xal:PostalCodeNumber>
</xal:PostalCode>
"#,
);
let postal_code = PostalCode::parse_eml(&xml, EMLParsingMode::Strict).unwrap();
assert_eq!(postal_code.number(), "1234 AB");
assert_eq!(postal_code.postal_code_type, None);
assert_eq!(postal_code.number.number_type, None);
assert_eq!(postal_code.number.code, None);
let xml_output = test_write_eml_element(&postal_code, &[NS_XAL]).unwrap();
assert_eq!(xml_output, xml);
}
}