use super::{
flags::IntoTokensFlags,
stream::{ParseError, TokenStream},
token::Token,
traits::{IntoToken, IntoTokens},
transform::{
add_stress, detect_stress, normalize, tokenize, tokens_to_string, unstress_vowels,
},
};
use crate::category::Stress;
use std::str::FromStr;
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TokenList {
pub tokens: Vec<Token>,
pub stress: Option<Stress>,
}
impl TokenList {
pub const fn new() -> Self {
TokenList {
tokens: Vec::new(),
stress: None,
}
}
pub fn stream(&self) -> TokenStream {
TokenStream {
tokens: &self.tokens[..],
stress: self.stress,
start: 0,
end: self.tokens.len(),
}
}
pub fn push<T: IntoToken>(&mut self, token: T) {
self.tokens.push(token.into_token());
}
pub fn append<T: IntoTokens>(&mut self, item: &T, flags: IntoTokensFlags) {
item.append_tokens_to(self, flags);
}
pub fn set_stress(&mut self, stress: Stress) {
self.stress = Some(stress);
}
}
impl FromStr for TokenList {
type Err = ParseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let source = normalize(s);
let stress = detect_stress(&source)?;
let source = unstress_vowels(&source);
let tokens = tokenize(&source)?;
Ok(TokenList { tokens, stress })
}
}
impl ToString for TokenList {
fn to_string(&self) -> String {
let word = tokens_to_string(&self.tokens);
if let Some(stress) = self.stress {
return add_stress(&word, stress).unwrap_or(word);
}
return word;
}
}