use hashbrown::HashMap;
use super::first_match_of::FirstMatchOf;
use super::{Expr, SequenceExpr};
use crate::{CharString, Span, Token};
#[derive(Default)]
pub struct WordExprGroup<E>
where
E: Expr,
{
exprs: HashMap<CharString, E>,
}
impl WordExprGroup<FirstMatchOf> {
pub fn add(&mut self, word: &str, expr: impl Expr + 'static) {
let chars = word.chars().collect();
if let Some(group) = self.exprs.get_mut(&chars) {
group.add(expr);
} else {
let mut group = FirstMatchOf::default();
group.add(expr);
self.exprs.insert(chars, group);
}
}
pub fn add_word(&mut self, word: &'static str) {
self.add(word, SequenceExpr::default().then_exact_word(word));
}
}
impl<E> Expr for WordExprGroup<E>
where
E: Expr,
{
fn run(&self, cursor: usize, tokens: &[Token], source: &[char]) -> Option<Span<Token>> {
let first = tokens.get(cursor)?;
if !first.kind.is_word() {
return None;
}
let word_chars = first.get_ch(source);
let inner_pattern = self.exprs.get(word_chars)?;
inner_pattern.run(cursor, tokens, source)
}
}