use crate::meta::Meta;
pub trait Res: Meta {}
pub trait Set {
type Res: Res;
fn iter(&self) -> impl Iterator<Item = &Self::Res>;
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Res>;
fn subset<F>(&mut self, filter: F) -> SubSet<Self, F>
where
F: Fn(&Self::Res) -> bool,
Self: Sized,
{
SubSet { set: self, filter }
}
}
pub trait Sets {
type Set: Set;
fn iter(&self) -> impl Iterator<Item = &Self::Set>;
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Set>;
fn subset<F>(&mut self, filter: F) -> SubSets<Self, F>
where
F: Fn(&Self::Set) -> bool,
Self: Sized,
{
SubSets { sets: self, filter }
}
}
pub struct SubSet<'a, S, F>
where
S: Set + 'a,
F: Fn(&S::Res) -> bool,
{
set: &'a mut S,
filter: F,
}
impl<'a, S, F> Set for SubSet<'a, S, F>
where
S: Set + 'a,
F: Fn(&S::Res) -> bool,
{
type Res = S::Res;
fn iter(&self) -> impl Iterator<Item = &Self::Res> {
self.set.iter().filter(|r| (self.filter)(*r))
}
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Res> {
self.set.iter_mut().filter(|r| (self.filter)(*r))
}
}
pub struct SubSets<'a, SS, F>
where
SS: Sets + 'a,
F: Fn(&SS::Set) -> bool,
{
sets: &'a mut SS,
filter: F,
}
impl<'a, SS, F> Sets for SubSets<'a, SS, F>
where
SS: Sets + 'a,
F: Fn(&SS::Set) -> bool,
{
type Set = SS::Set;
fn iter(&self) -> impl Iterator<Item = &Self::Set> {
self.sets.iter().filter(|s| (self.filter)(*s))
}
fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Set> {
self.sets.iter_mut().filter(|s| (self.filter)(*s))
}
}