use crate::extensions::Extensions;
use super::Matcher;
pub trait IteratorMatcherExt<'a, M, Input>: Iterator<Item = &'a M> + 'a
where
M: Matcher<Input>,
{
fn matches_and(self, ext: Option<&Extensions>, input: &Input) -> bool;
fn matches_or(self, ext: Option<&Extensions>, input: &Input) -> bool;
}
impl<'a, I, M, Input> IteratorMatcherExt<'a, M, Input> for I
where
I: Iterator<Item = &'a M> + 'a,
M: Matcher<Input>,
{
fn matches_and(self, ext: Option<&Extensions>, input: &Input) -> bool {
match ext {
None => {
for matcher in self {
if !matcher.matches(None, input) {
return false;
}
}
true
}
Some(ext) => {
let inner_ext = Extensions::new();
for matcher in self {
if !matcher.matches(Some(&inner_ext), input) {
return false;
}
}
ext.extend(&inner_ext);
true
}
}
}
fn matches_or(self, ext: Option<&Extensions>, input: &Input) -> bool {
let mut it = self.peekable();
if it.peek().is_none() {
return true;
}
match ext {
None => {
for matcher in it {
if matcher.matches(None, input) {
return true;
}
}
false
}
Some(ext) => {
for matcher in it {
let inner_ext = Extensions::new();
if matcher.matches(Some(&inner_ext), input) {
ext.extend(&inner_ext);
return true;
}
}
false
}
}
}
}