pub mod checker;
use std::{
marker::PhantomData,
mem,
ops::{Add, RangeBounds, RangeInclusive, Sub},
};
use crate::{
AnyIncDecCpCmp, CpCmp, DefaultValues, GetBeginEnd, GetBeginEndOption, IncDecCpCmp,
NumberIncDecCpCmp, RangeRelation, RiFactory, iter::consolidate::checker::ConsolidateChecker,
};
use crate::{range_relation, utils::consolidate};
#[derive(Clone, Copy)]
pub enum ConsolidationOrder {
Forward,
Reverse,
}
impl ConsolidationOrder {
pub fn check_direction<T>(&self, state: &RangeRelation<T>) -> Result<(), &'static str> {
match state {
RangeRelation::Invalid(_) => Err("Range Compare contained Invalid range(s)"),
RangeRelation::Last(_) | RangeRelation::Overlap(_) => Ok(()),
RangeRelation::After(_) => match self {
Self::Forward => {
Err("Out of Forward Sequence, Expected: Before|Last|Overlap, got: After")
}
Self::Reverse => Ok(()),
},
RangeRelation::Before(_) => match self {
Self::Forward => Ok(()),
Self::Reverse => {
Err("Out of Forward Sequence, Expected: After|Last|Overlap, got: Before")
}
},
}
}
pub fn wants_next<T>(&self, r: &RangeRelation<T>) -> bool {
match r {
RangeRelation::Invalid(_) => false,
RangeRelation::Last(_) | RangeRelation::Overlap(_) => return true,
RangeRelation::After(_) => match self {
Self::Forward => return false,
Self::Reverse => return true,
},
RangeRelation::Before(_) => match self {
Self::Forward => return true,
Self::Reverse => return false,
},
}
}
pub fn check_position<T>(
&self,
a: &impl GetBeginEnd<T>,
b: &impl GetBeginEnd<T>,
t: &impl CpCmp<T>,
) -> (bool, bool) {
let r = range_relation(a, b, t);
match r {
RangeRelation::Invalid(_) => (false, false),
RangeRelation::Last(_) => (true, true),
RangeRelation::Overlap(_) => match self {
ConsolidationOrder::Forward => (true, t.lt(b.get_end(), a.get_end())),
ConsolidationOrder::Reverse => (true, t.lt(a.get_begin(), b.get_begin())),
},
RangeRelation::After(_) => match self {
Self::Forward => return (false, true),
Self::Reverse => return (false, false),
},
RangeRelation::Before(_) => match self {
Self::Forward => return (false, false),
Self::Reverse => return (false, true),
},
}
}
pub fn is_beyond<T>(
&self,
a: &impl GetBeginEnd<T>,
b: &impl GetBeginEnd<T>,
t: &impl CpCmp<T>,
) -> bool {
match self {
Self::Forward => t.lt(b.get_end(), a.get_end()),
Self::Reverse => t.lt(a.get_begin(), b.get_begin()),
}
}
pub fn is_before<T>(
&self,
a: &impl GetBeginEnd<T>,
b: &impl GetBeginEnd<T>,
t: &impl CpCmp<T>,
) -> bool {
match self {
Self::Forward => t.lt(a.get_end(), b.get_end()),
Self::Reverse => t.lt(b.get_begin(), a.get_begin()),
}
}
}
pub struct Consolidate<
T,
V,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
F: GetBeginEndOption<T, R>,
I: Iterator<Item = S>,
C: IncDecCpCmp<T, V>,
> {
iter: I,
last: Option<(R, Vec<(usize, S)>)>,
next: Option<RangeRelation<(R, Vec<(usize, S)>)>>,
cmp: C,
facotry: F,
offset: usize,
rebound: V,
_p: PhantomData<(T, S)>,
}
impl<
T,
V,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
F: GetBeginEndOption<T, R>,
I: Iterator<Item = S>,
C: IncDecCpCmp<T, V>,
> Consolidate<T, V, R, S, F, I, C>
{
pub fn new(mut iter: I, cmp: C, factory: F, rebound: V) -> Self {
let mut last = None;
let (offset, next) = consolidate(&mut last, &mut iter, &cmp, &rebound, &factory, 0);
return Self {
iter,
last,
next,
cmp: cmp,
facotry: factory,
offset,
rebound,
_p: PhantomData,
};
}
pub fn get_cmp(&self) -> &C {
return &self.cmp;
}
pub fn get_factory(&self) -> &F {
return &self.facotry;
}
}
impl<
T,
V,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
F: GetBeginEndOption<T, R>,
I: Iterator<Item = S>,
C: IncDecCpCmp<T, V>,
> Consolidate<T, V, R, S, F, I, C>
{
pub fn to_consolidate_checker(
self,
order: ConsolidationOrder,
) -> ConsolidateChecker<T, V, R, S, F, I, C> {
return ConsolidateChecker::new(order, self);
}
}
impl<T, S: RangeBounds<T>, I: Iterator<Item = S>>
Consolidate<T, T, RangeInclusive<T>, S, RiFactory<T>, I, NumberIncDecCpCmp<T>>
where
NumberIncDecCpCmp<T>: DefaultValues<T, T>,
T: Copy + Clone,
{
pub fn num(iter: I, cmp: NumberIncDecCpCmp<T>, factory: RiFactory<T>) -> Self {
return Self::new(iter, cmp, factory, cmp.default_rebound());
}
}
impl<T, S: RangeBounds<T>, I: Iterator<Item = S>>
Consolidate<T, T, RangeInclusive<T>, S, RiFactory<T>, I, NumberIncDecCpCmp<T>>
where
NumberIncDecCpCmp<T>: DefaultValues<T, T>,
T: Copy + Clone,
{
pub fn num_defaults(iter: I) -> Self {
let cmp = NumberIncDecCpCmp::<T>::defaults();
let factory = RiFactory::<T>::new();
return Self::num(iter, cmp, factory);
}
}
impl<V, R: GetBeginEnd<T>, S: RangeBounds<T>, T, I: Iterator<Item = S>, F: GetBeginEndOption<T, R>>
Consolidate<T, V, R, S, F, I, AnyIncDecCpCmp<T>>
where
V: Copy,
T: PartialOrd + Copy + Add<V, Output = T> + Sub<V, Output = T>,
{
pub fn any(iter: I, cmp: AnyIncDecCpCmp<T>, factory: F, rebound: V) -> Self {
return Self::new(iter, cmp, factory, rebound);
}
}
impl<T, V, I: Iterator<Item = RangeInclusive<T>>>
Consolidate<T, V, RangeInclusive<T>, RangeInclusive<T>, RiFactory<T>, I, AnyIncDecCpCmp<T>>
where
V: Copy,
T: PartialOrd + Copy + Add<V, Output = T> + Sub<V, Output = T>,
{
pub fn any_defaults(iter: I, min: T, max: T, rebound: V) -> Self {
return Self::any(
iter,
AnyIncDecCpCmp::new(min, max),
RiFactory::new(),
rebound,
);
}
}
impl<
T,
V,
R: GetBeginEnd<T>,
S: RangeBounds<T>,
F: GetBeginEndOption<T, R>,
I: Iterator<Item = S>,
C: IncDecCpCmp<T, V>,
> Iterator for Consolidate<T, V, R, S, F, I, C>
{
type Item = RangeRelation<(R, Vec<(usize, S)>)>;
fn next(&mut self) -> Option<Self::Item> {
if self.next.is_none() {
return None;
}
let next;
(self.offset, next) = consolidate(
&mut self.last,
&mut self.iter,
&self.cmp,
&self.rebound,
&self.facotry,
self.offset,
);
return mem::replace(&mut self.next, next);
}
}