use svara::phoneme::Phoneme;
use crate::dictionary::entry::Region;
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct StaticPronunciation {
pub phonemes: &'static [Phoneme],
pub frequency: Option<f32>,
pub region: Option<Region>,
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct StaticEntry {
pub pronunciations: &'static [StaticPronunciation],
}
impl StaticEntry {
#[must_use]
pub fn primary_phonemes(&self) -> &'static [Phoneme] {
self.pronunciations[0].phonemes
}
#[must_use]
pub fn all(&self) -> &'static [StaticPronunciation] {
self.pronunciations
}
#[must_use]
pub fn len(&self) -> usize {
self.pronunciations.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
false
}
}
#[cfg(feature = "phf")]
include!(concat!(env!("OUT_DIR"), "/generated_phf_dict.rs"));
#[cfg(feature = "phf")]
#[must_use]
pub fn lookup(word: &str) -> Option<&'static [Phoneme]> {
lookup_entry(word).map(|e| e.primary_phonemes())
}
#[cfg(feature = "phf")]
#[must_use]
pub fn lookup_entry(word: &str) -> Option<&'static StaticEntry> {
if word.bytes().all(|b| !b.is_ascii_uppercase()) {
PHF_ENGLISH_DICT.get(word)
} else {
let key = word.to_lowercase();
PHF_ENGLISH_DICT.get(key.as_str())
}
}
#[cfg(feature = "phf")]
#[must_use]
pub fn len() -> usize {
PHF_ENGLISH_DICT.len()
}
#[cfg(feature = "phf")]
#[must_use]
pub fn is_empty() -> bool {
PHF_ENGLISH_DICT.is_empty()
}
#[cfg(all(test, feature = "phf"))]
mod tests {
use super::*;
#[test]
fn test_static_lookup_hello() {
let phonemes = lookup("hello");
assert!(phonemes.is_some(), "hello should be in static dict");
assert!(!phonemes.unwrap().is_empty());
}
#[test]
fn test_static_lookup_the() {
assert!(lookup("the").is_some());
}
#[test]
fn test_static_lookup_case_insensitive() {
assert_eq!(lookup("Hello"), lookup("hello"));
}
#[test]
fn test_static_lookup_miss() {
assert!(lookup("zxqvbnm").is_none());
}
#[test]
fn test_static_len() {
assert!(len() >= 10000);
}
#[test]
fn test_static_entry_hello() {
let entry = lookup_entry("hello").unwrap();
assert!(!entry.is_empty());
assert_eq!(entry.len(), 1); }
#[test]
fn test_static_entry_read_variants() {
let entry = lookup_entry("read").unwrap();
assert!(
entry.len() >= 2,
"read should have 2+ variants, got {}",
entry.len()
);
}
#[test]
fn test_static_matches_dynamic() {
let dynamic = crate::PronunciationDict::english();
let words = ["hello", "the", "computer", "beautiful", "psychology"];
for word in &words {
let static_phonemes = lookup(word);
let dynamic_phonemes = dynamic.lookup(word);
assert_eq!(static_phonemes, dynamic_phonemes, "mismatch for '{word}'");
}
}
}