use std::iter::FilterMap;
#[derive(Debug, Eq, PartialEq)]
pub enum CandidateSolution<T = usize> {
Incomplete,
Sat(Vec<T>),
Unsat(Vec<T>),
}
#[derive(Debug)]
pub enum Solution<T = usize> {
Sat(Vec<T>),
Unsat(Vec<T>),
}
type MaybeSolution<T> = Option<Solution<T>>;
type MaybeFilteredSolution<T> = Option<Vec<T>>;
type SolutionMap<S, T> = FilterMap<S, fn(CandidateSolution<T>) -> MaybeSolution<T>>;
type SpecificSolutionMap<S, T> = FilterMap<S, fn(CandidateSolution<T>) -> MaybeFilteredSolution<T>>;
pub trait IterSolveExt<T>: Iterator<Item = CandidateSolution<T>> + Sized {
fn solution_iter(self) -> SolutionMap<Self, T> {
self.filter_map(|s| match s {
CandidateSolution::<T>::Sat(sat) => Some(Solution::Sat(sat)),
CandidateSolution::<T>::Unsat(unsat) => Some(Solution::Unsat(unsat)),
CandidateSolution::<T>::Incomplete => None,
})
}
fn sat_iter(self) -> SpecificSolutionMap<Self, T> {
self.filter_map(|s| match s {
CandidateSolution::<T>::Sat(sat) => Some(sat),
_ => None,
})
}
fn unsat_iter(self) -> SpecificSolutionMap<Self, T> {
self.filter_map(|s| match s {
CandidateSolution::<T>::Unsat(sat) => Some(sat),
_ => None,
})
}
}
impl<T, I: Iterator<Item = CandidateSolution<T>>> IterSolveExt<T> for I {}