Skip to main content

harper_core/expr/
all.rs

1use crate::{
2    Span, Token,
3    expr::{AsBoxedExpr, Expr},
4};
5
6/// An [`Expr`] that matches against tokens if and only if all of its children do.
7/// This can be useful for situations where you have multiple expressions that represent a grammatical
8/// error, but you need _all_ of them to match to be certain.
9///
10/// It will return the position of the farthest window.
11#[derive(Default)]
12pub struct All {
13    children: Vec<Box<dyn Expr>>,
14}
15
16impl All {
17    pub fn new(children: impl IntoIterator<Item = impl AsBoxedExpr>) -> Self {
18        Self {
19            children: children.into_iter().map(|e| e.into_boxed_expr()).collect(),
20        }
21    }
22
23    pub fn add(&mut self, e: impl Expr + 'static) {
24        self.children.push(Box::new(e));
25    }
26}
27
28impl Expr for All {
29    fn run(&self, cursor: usize, tokens: &[Token], source: &[char]) -> Option<Span<Token>> {
30        let mut longest: Option<Span<Token>> = None;
31
32        for expr in self.children.iter() {
33            let window = expr.run(cursor, tokens, source)?;
34
35            if let Some(longest_window) = longest {
36                if window.len() > longest_window.len() {
37                    longest = Some(window);
38                }
39            } else {
40                longest = Some(window);
41            }
42        }
43
44        longest
45    }
46}