use crate::text_expand::{ExpandResult, ExpandTask, ExpandUnit};
use std::collections::VecDeque;
use super::number_to_words_en;
pub struct EnNumberExpandTask;
impl ExpandTask for EnNumberExpandTask {
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_en(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_en_number_expansion() {
let task = EnNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Number("123".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(n, units) = res {
assert_eq!(n, 1);
assert_eq!(
units,
vec![
ExpandUnit::Word("one".into()),
ExpandUnit::Word("hundred".into()),
ExpandUnit::Word("and".into()),
ExpandUnit::Word("twenty".into()),
ExpandUnit::Word("three".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[0], ExpandUnit::Word("one".into()));
assert_eq!(units[1], ExpandUnit::Word("thousand".into()));
assert_eq!(units[2], ExpandUnit::Word("and".into()));
assert_eq!(units[3], ExpandUnit::Word("five".into()));
} else {
panic!("Expected Replace result for 1005");
}
}
#[test]
fn test_en_number_zero() {
let task = EnNumberExpandTask;
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("zero".into())]);
} else {
panic!("Expected Replace result for zero");
}
}
#[test]
fn test_en_number_single_digit() {
let task = EnNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Number("7".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(n, units) = res {
assert_eq!(n, 1);
assert_eq!(units, vec![ExpandUnit::Word("seven".into())]);
} else {
panic!("Expected Replace result for single digit");
}
}
#[test]
fn test_en_number_teens() {
let task = EnNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Number("13".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(_, units) = res {
assert_eq!(units, vec![ExpandUnit::Word("thirteen".into())]);
} else {
panic!("Expected Replace result for teen number");
}
}
#[test]
fn test_en_number_millions() {
let task = EnNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Number("1000000".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(_, units) = res {
assert_eq!(
units,
vec![
ExpandUnit::Word("one".into()),
ExpandUnit::Word("million".into()),
]
);
} else {
panic!("Expected Replace result for one million");
}
}
#[test]
fn test_en_number_non_number_returns_none() {
let task = EnNumberExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Word("hello".into()));
let res = task.expand(&queue);
assert!(res.is_none(), "Non-number input should return None");
}
}