use crate::text_expand::{ExpandResult, ExpandTask, ExpandUnit};
use std::collections::VecDeque;
pub struct EnNegativeExpandTask;
impl ExpandTask for EnNegativeExpandTask {
fn expand(&self, queue: &VecDeque<ExpandUnit>) -> Option<ExpandResult> {
if queue.len() < 2 {
if let Some(ExpandUnit::Mark('-')) = queue.front() {
return Some(ExpandResult::Maybe);
}
return None;
}
match (queue.front(), queue.get(1)) {
(Some(ExpandUnit::Mark('-')), Some(ExpandUnit::Number(n))) => {
Some(ExpandResult::Replace(
2,
vec![
ExpandUnit::Word("negative".into()),
ExpandUnit::Number(n.clone()),
],
))
}
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_en_negative_expansion() {
let task = EnNegativeExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Mark('-'));
queue.push_back(ExpandUnit::Number("42".into()));
let res = task.expand(&queue).unwrap();
if let ExpandResult::Replace(n, units) = res {
assert_eq!(n, 2);
assert_eq!(units[0], ExpandUnit::Word("negative".into()));
assert_eq!(units[1], ExpandUnit::Number("42".into()));
} else {
panic!("Expected Replace result");
}
}
#[test]
fn test_en_negative_no_expand_hyphen_word() {
let task = EnNegativeExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Mark('-'));
queue.push_back(ExpandUnit::Word("stop".into()));
let res = task.expand(&queue);
assert!(
res.is_none(),
"Hyphen before word should not expand as negative"
);
}
#[test]
fn test_en_negative_maybe_single_mark() {
let task = EnNegativeExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Mark('-'));
let res = task.expand(&queue);
assert!(
matches!(res, Some(ExpandResult::Maybe)),
"Single '-' mark should return Maybe"
);
}
#[test]
fn test_en_negative_non_mark_returns_none() {
let task = EnNegativeExpandTask;
let mut queue = VecDeque::new();
queue.push_back(ExpandUnit::Word("hello".into()));
let res = task.expand(&queue);
assert!(res.is_none(), "Non-dash input should return None");
}
}