[lib] Add PronounList struct for serializing/deserializing lists of pronouns

This commit is contained in:
Emi Simpson 2021-10-30 11:39:51 -04:00
parent 37c0390678
commit 1e78a528ce
Signed by: Emi
GPG key ID: A12F2C2FFDC3D847

View file

@ -42,6 +42,8 @@ pub mod user_preferences;
pub mod util; pub mod util;
mod weighted_table; mod weighted_table;
use std::error::Error;
use core::str::FromStr;
use std::fmt; use std::fmt;
use serde::{Serialize, Deserialize, self}; use serde::{Serialize, Deserialize, self};
@ -248,3 +250,108 @@ impl From<Pronoun> for [String; 5] {
] ]
} }
} }
/// An intermediary struct to facilitate parsing and serializing lists of pronouns
///
/// ## Examples
///
/// ```
/// use pronouns_today::PronounList;
///
/// let list: PronounList = vec![
/// ["she", "her", "her", "hers", "herself" ].into(),
/// ["he", "him", "his", "his", "himself" ].into(),
/// ].into();
///
/// assert_eq!(
/// list.to_string(),
/// "she/her/her/hers/herself,he/him/his/his/himself"
/// )
/// ```
///
/// ```
/// use pronouns_today::PronounList;
/// use pronouns_today::Pronoun;
///
/// let unparsed = "sea/sear/sear/sears/seaself,po/pony/ponys/ponys/ponyself";
/// let parsed: PronounList = unparsed.parse().unwrap();
/// let parsed_vec: Vec<Pronoun> = parsed.into();
///
/// assert_eq!(
/// parsed_vec,
/// vec![
/// ["sea", "sear", "sear", "sears", "seaself" ].into(),
/// ["po", "pony", "ponys", "ponys", "ponyself" ].into(),
/// ]
/// )
/// ```
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct PronounList(Vec<Pronoun>);
impl fmt::Display for PronounList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for set_i in 0..self.0.len() {
let set = &self.0[set_i];
if set_i > 0 {
write!(f, ",")?;
}
write!(f,
"{}/{}/{}/{}/{}",
set.subject_pronoun,
set.object_pronoun,
set.possesive_determiner,
set.possesive_pronoun,
set.reflexive_pronoun,
)?;
}
Ok(())
}
}
impl FromStr for PronounList {
type Err = PronounListError;
fn from_str(s: &str) -> Result<PronounList, Self::Err> {
s.split(',')
.map(|s| {
let split: Vec<&str> = s.split('/').collect();
if split.len() != 5 {
Err(PronounListError)
} else {
Ok(Pronoun {
subject_pronoun: split[0].into(),
object_pronoun: split[1].into(),
possesive_determiner: split[2].into(),
possesive_pronoun: split[3].into(),
reflexive_pronoun: split[4].into(),
})
}
})
.collect::<Result<Vec<Pronoun>, PronounListError>>()
.map(PronounList)
}
}
impl From<PronounList> for Vec<Pronoun> {
fn from(list: PronounList) -> Vec<Pronoun> {
list.0
}
}
impl From<Vec<Pronoun>> for PronounList {
fn from(list: Vec<Pronoun>) -> PronounList {
PronounList(list)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PronounListError;
impl fmt::Display for PronounListError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("Pronouns must be written in their five-form form, with each form
seperated by a slash (/), and each set seperated by a comma (,). For
example: 'he/him/his/his/himself,she/her/her/hers/herself'")
}
}
impl Error for PronounListError {}