use crate::Pred;
use crate::Pred2;
use std::fmt::Debug;
use std::fmt::Formatter;
use std::fmt::Result as FmtResult;
std_prelude!();
fn iter_adjacent<T: Copy, I: Iterator<Item = T>>(mut iter: I) -> impl Iterator<Item = (T, T)> {
let fst = iter.next();
iter.scan(fst, |x, y| x.replace(y).map(|x| (x, y)))
}
#[derive(Clone, Copy, Default)]
pub struct AllAdj<P>(pub P);
impl<P: Debug> Debug for AllAdj<P> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "AllAdj<{:?}>", self.0)
}
}
impl<T: ?Sized, U: ?Sized, P: Pred2<U>> Pred<T> for AllAdj<P>
where
for<'a> &'a T: IntoIterator<Item = &'a U>,
{
fn accept(t: &T) -> bool {
iter_adjacent(t.into_iter()).all(P::accept_tup)
}
}
#[derive(Clone, Copy, Default)]
pub struct AnyAdj<P>(pub P);
impl<P: Debug> Debug for AnyAdj<P> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "AnyAdj<{:?}>", self.0)
}
}
impl<T: ?Sized, U: ?Sized, P: Pred2<U>> Pred<T> for AnyAdj<P>
where
for<'a> &'a T: IntoIterator<Item = &'a U>,
{
fn accept(t: &T) -> bool {
iter_adjacent(t.into_iter()).any(P::accept_tup)
}
}
#[derive(Clone, Copy, Default)]
pub struct All<P>(pub P);
impl<P: Debug> Debug for All<P> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "All<{:?}>", self.0)
}
}
impl<T: ?Sized, U: ?Sized, P: Pred<U>> Pred<T> for All<P>
where
for<'a> &'a T: IntoIterator<Item = &'a U>,
{
fn accept(t: &T) -> bool {
t.into_iter().all(P::accept)
}
}
#[derive(Clone, Copy, Default)]
pub struct Any<P>(pub P);
impl<P: Debug> Debug for Any<P> {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
write!(f, "Any<{:?}>", self.0)
}
}
impl<T: ?Sized, U: ?Sized, P: Pred<U>> Pred<T> for Any<P>
where
for<'a> &'a T: IntoIterator<Item = &'a U>,
{
fn accept(t: &T) -> bool {
t.into_iter().any(P::accept)
}
}