use crate::text_expand::{ExpandResult, ExpandTask, ExpandUnit};
use std::collections::VecDeque;
use super::number_to_words_vi;
pub struct ViNumberExpandTask;
impl ExpandTask for ViNumberExpandTask {
fn expand(&self, queue: &VecDeque<ExpandUnit>) -> Option<ExpandResult> {
if let Some(ExpandUnit::Number(num)) = queue.front()
&& let Ok(val) = num.parse::<u64>()
{
let words = number_to_words_vi(val);
if !words.is_empty() {
return Some(ExpandResult::Replace(
1,
words
.into_iter()
.map(|w| ExpandUnit::Word(w.into()))
.collect(),
));
}
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vi_number_expansion() {
let task = ViNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Number("123".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(_, units) = res {
assert_eq!(
units,
vec![
ExpandUnit::Word("một".into()),
ExpandUnit::Word("trăm".into()),
ExpandUnit::Word("hai".into()),
ExpandUnit::Word("mươi".into()),
ExpandUnit::Word("ba".into()),
]
);
} else {
panic!("Expected Replace result");
}
queue.clear();
queue.push_back(ExpandUnit::Number("1005".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(_, units) = res {
assert_eq!(
units,
vec![
ExpandUnit::Word("một".into()),
ExpandUnit::Word("nghìn".into()),
ExpandUnit::Word("không".into()),
ExpandUnit::Word("trăm".into()),
ExpandUnit::Word("linh".into()),
ExpandUnit::Word("năm".into()),
]
);
} else {
panic!("Expected Replace result for 1005");
}
queue.clear();
queue.push_back(ExpandUnit::Number("21".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(_, units) = res {
assert_eq!(
units,
vec![
ExpandUnit::Word("hai".into()),
ExpandUnit::Word("mươi".into()),
ExpandUnit::Word("mốt".into()),
]
);
} else {
panic!("Expected Replace result for 21");
}
}
#[test]
fn test_vi_number_zero() {
let task = ViNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Number("0".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(n, units) = res {
assert_eq!(n, 1);
assert_eq!(units, vec![ExpandUnit::Word("không".into())]);
} else {
panic!("Expected Replace result for zero");
}
}
#[test]
fn test_vi_number_non_number_returns_none() {
let task = ViNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Word("xin".into()));
let res = task.expand(&queue);
assert!(res.is_none(), "Non-number input should return None");
}
}