use crate::conversion::latin::{CONSONANTS, VOWELS};
use std::collections::HashMap;
pub fn separate(latn: &str) -> Vec<String> {
let chars: Vec<char> = latn.chars().collect();
let n = chars.len();
let mut syllable_map: HashMap<usize, usize> = HashMap::new();
let mut syllable_count = 1;
for i in 0..n {
if VOWELS.contains(chars[i]) {
if i > 0 && CONSONANTS.contains(chars[i - 1]) {
syllable_map.insert(i - 1, syllable_count);
}
syllable_map.insert(i, syllable_count);
syllable_count += 1;
}
}
for i in 0..n {
if !syllable_map.contains_key(&i) {
let prev = i
.checked_sub(1)
.and_then(|p| syllable_map.get(&p))
.copied()
.unwrap_or(0);
syllable_map.insert(i, prev);
}
}
let mut syllables: Vec<String> = Vec::new();
let mut current_group_id = 1;
let mut head = 0;
for i in 0..n {
if *syllable_map.get(&i).unwrap_or(&0) != current_group_id {
current_group_id = *syllable_map.get(&i).unwrap_or(&0);
syllables.push(chars[head..i].iter().collect());
head = i;
}
}
syllables.push(chars[head..].iter().collect());
syllables.iter().map(|s| s.replace('\'', "")).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_separate() {
let separated = separate("eyaykosiramsuypa");
assert_eq!(separated, vec!["e", "yay", "ko", "si", "ram", "suy", "pa"]);
}
#[test]
fn separate_handles_glottal_stop() {
assert_eq!(separate("ne\u{2019}"), vec!["ne\u{2019}"]);
assert_eq!(separate("a\u{2019}e"), vec!["a", "\u{2019}e"]);
}
#[test]
fn separate_bare_consonant_does_not_panic() {
let _ = separate("k");
let _ = separate("");
}
}