use crate::dictionary::Dictionary;
use crate::dictionary::stress::StressOpts;
use crate::embedded_data::materialized_data_dir;
use crate::error::{Error, Result};
use crate::phoneme::PhonemeData;
use crate::semantic::{Language, WordPhoneme};
use crate::translate::word_to_phonemes;
use std::sync::Arc;
pub struct WordPhonemizer {
language: Language,
dict: Dictionary,
phdata: Arc<PhonemeData>,
stress_opts: StressOpts,
}
impl WordPhonemizer {
pub fn new(language: Language) -> Result<Self> {
let data_dir = materialized_data_dir()?;
let phdata = Arc::new(PhonemeData::load(data_dir)?);
Self::new_with_data(language, phdata)
}
pub fn new_with_data(language: Language, phdata: Arc<PhonemeData>) -> Result<Self> {
let data_dir = materialized_data_dir()?;
let dict = Dictionary::load(language.as_str(), data_dir)?;
let stress_opts = StressOpts::for_lang(language.as_str());
Ok(Self {
language,
dict,
phdata,
stress_opts,
})
}
pub fn phonemize_word(&self, word: &str) -> Result<WordPhoneme> {
if word.is_empty() {
return Err(Error::InvalidData("word must not be empty".into()));
}
let table = self.phdata.get_active_table(self.language.as_str())?;
let normalized = word.to_lowercase();
let result = word_to_phonemes(
&normalized,
&self.dict,
&self.phdata,
table,
&self.stress_opts,
);
Ok(WordPhoneme::from_raw(
self.language,
normalized,
result.phonemes,
result.dict_flags,
&self.phdata,
))
}
pub fn language(&self) -> Language {
self.language
}
}