use crate::{
prelude::*,
romanize::{
stream::{ParseError, TokenStream},
token::Token,
},
};
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum Word {
Formative(word::ShortcutCheckedFormative),
Referential(word::GeneralReferential),
Affixual(word::AffixualAdjunct),
Modular(word::ModularAdjunct),
MCS(word::MCSAdjunct),
Parsing(word::ParsingAdjunct),
Register(word::RegisterAdjunct),
Suppletive(word::SuppletiveAdjunct),
Bias(word::BiasAdjunct),
Numeric(word::NumericAdjunct),
}
impl Gloss for Word {
fn gloss(&self, flags: GlossFlags) -> String {
match self {
Self::Formative(value) => value.gloss(flags),
Self::Referential(value) => value.gloss(flags),
Self::Affixual(value) => value.gloss(flags),
Self::Modular(value) => value.gloss(flags),
Self::MCS(value) => value.gloss(flags),
Self::Parsing(value) => value.gloss(flags),
Self::Register(value) => value.gloss(flags),
Self::Suppletive(value) => value.gloss(flags),
Self::Bias(value) => value.gloss(flags),
Self::Numeric(value) => value.gloss(flags),
}
}
}
impl FromTokens for Word {
fn parse_volatile(stream: &mut TokenStream, flags: FromTokenFlags) -> Result<Self, ParseError> {
macro_rules! check_all {
($last:ident, $($variant:ident),+) => {{
$(if let Ok(value) = stream.parse_entire(flags) {
return Ok(Self::$variant(value));
})+
let value = stream.parse(flags)?;
if stream.is_done() {
Ok(Self::$last(value))
} else {
Err(ParseError::TooManyTokens)
}
}};
}
match stream.peek() {
Some(Token::V(_)) => check_all!(Formative, Parsing, Modular, Affixual, Referential),
Some(Token::C(_)) => check_all!(Formative, Bias, Affixual, Referential),
Some(Token::H(_)) => check_all!(Formative, Suppletive, Register, MCS, Modular),
Some(Token::N(_)) => check_all!(Formative, Numeric, Affixual),
Some(Token::Schwa) => check_all!(Referential, Affixual),
Some(Token::ÜA) => Err(ParseError::WordInitialÜA),
Some(Token::GlottalStop) => Err(ParseError::WordInitialGlottalStop),
None => Err(ParseError::WordEmpty),
}
}
}
impl IntoTokens for Word {
fn append_tokens_to(&self, list: &mut TokenList, flags: IntoTokensFlags) {
match self {
Self::Formative(value) => value.append_tokens_to(list, flags),
Self::Referential(value) => value.append_tokens_to(list, flags),
Self::Affixual(value) => value.append_tokens_to(list, flags),
Self::Modular(value) => value.append_tokens_to(list, flags),
Self::MCS(value) => value.append_tokens_to(list, flags),
Self::Parsing(value) => value.append_tokens_to(list, flags),
Self::Register(value) => value.append_tokens_to(list, flags),
Self::Suppletive(value) => value.append_tokens_to(list, flags),
Self::Bias(value) => value.append_tokens_to(list, flags),
Self::Numeric(value) => value.append_tokens_to(list, flags),
}
}
}