use std::{
fmt::{self, Display, Formatter, Write},
str::FromStr,
};
use crate::{
error::InvalidValueError,
syntax::{split_unescaped, unescape_text, write_escaped_text},
};
fn write_component(f: &mut Formatter, list: &[String]) -> fmt::Result {
for (i, item) in list.iter().enumerate() {
if i > 0 {
f.write_char(',')?;
}
write_escaped_text(f, item, true)?;
}
Ok(())
}
fn parse_component(s: Option<&&str>) -> Vec<String> {
match s {
Some(s) if !s.is_empty() => {
split_unescaped(s, b',').into_iter().map(unescape_text).collect()
},
_ => Vec::new(),
}
}
fn write_components(f: &mut Formatter, components: &[&[String]], min: usize) -> fmt::Result {
let count =
components.iter().rposition(|list| !list.is_empty()).map_or(min, |last| min.max(last + 1));
for (i, list) in components[..count].iter().enumerate() {
if i > 0 {
f.write_char(';')?;
}
write_component(f, list)?;
}
Ok(())
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct NameValue {
pub family_names: Vec<String>,
pub given_names: Vec<String>,
pub additional_names: Vec<String>,
pub honorific_prefixes: Vec<String>,
pub honorific_suffixes: Vec<String>,
pub surname2: Vec<String>,
pub generation: Vec<String>,
}
impl NameValue {
#[inline]
pub fn new() -> Self {
Self::default()
}
}
impl Display for NameValue {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write_components(
f,
&[
&self.family_names,
&self.given_names,
&self.additional_names,
&self.honorific_prefixes,
&self.honorific_suffixes,
&self.surname2,
&self.generation,
],
5,
)
}
}
impl FromStr for NameValue {
type Err = InvalidValueError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts = split_unescaped(s, b';');
Ok(Self {
family_names: parse_component(parts.first()),
given_names: parse_component(parts.get(1)),
additional_names: parse_component(parts.get(2)),
honorific_prefixes: parse_component(parts.get(3)),
honorific_suffixes: parse_component(parts.get(4)),
surname2: parse_component(parts.get(5)),
generation: parse_component(parts.get(6)),
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct AddressValue {
pub post_office_boxes: Vec<String>,
pub extended_addresses: Vec<String>,
pub street_addresses: Vec<String>,
pub localities: Vec<String>,
pub regions: Vec<String>,
pub postal_codes: Vec<String>,
pub countries: Vec<String>,
pub rooms: Vec<String>,
pub apartments: Vec<String>,
pub floors: Vec<String>,
pub street_numbers: Vec<String>,
pub street_names: Vec<String>,
pub buildings: Vec<String>,
pub blocks: Vec<String>,
pub subdistricts: Vec<String>,
pub districts: Vec<String>,
pub landmarks: Vec<String>,
pub directions: Vec<String>,
}
impl AddressValue {
#[inline]
pub fn new() -> Self {
Self::default()
}
}
impl Display for AddressValue {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write_components(
f,
&[
&self.post_office_boxes,
&self.extended_addresses,
&self.street_addresses,
&self.localities,
&self.regions,
&self.postal_codes,
&self.countries,
&self.rooms,
&self.apartments,
&self.floors,
&self.street_numbers,
&self.street_names,
&self.buildings,
&self.blocks,
&self.subdistricts,
&self.districts,
&self.landmarks,
&self.directions,
],
7,
)
}
}
impl FromStr for AddressValue {
type Err = InvalidValueError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts = split_unescaped(s, b';');
Ok(Self {
post_office_boxes: parse_component(parts.first()),
extended_addresses: parse_component(parts.get(1)),
street_addresses: parse_component(parts.get(2)),
localities: parse_component(parts.get(3)),
regions: parse_component(parts.get(4)),
postal_codes: parse_component(parts.get(5)),
countries: parse_component(parts.get(6)),
rooms: parse_component(parts.get(7)),
apartments: parse_component(parts.get(8)),
floors: parse_component(parts.get(9)),
street_numbers: parse_component(parts.get(10)),
street_names: parse_component(parts.get(11)),
buildings: parse_component(parts.get(12)),
blocks: parse_component(parts.get(13)),
subdistricts: parse_component(parts.get(14)),
districts: parse_component(parts.get(15)),
landmarks: parse_component(parts.get(16)),
directions: parse_component(parts.get(17)),
})
}
}