use crate::intervals::absolute::{
AbsBoundPair,
AbsEndBound,
AbsInterval,
AbsStartBound,
BoundedAbsInterval,
EmptiableAbsBoundPair,
EmptiableAbsInterval,
HalfBoundedAbsInterval,
HasAbsBoundPair,
HasEmptiableAbsBoundPair,
};
use crate::intervals::ops::{BoundOrd, BoundOverlapDisambiguationRuleSet};
use crate::intervals::relative::{
BoundedRelInterval,
EmptiableRelBoundPair,
EmptiableRelInterval,
HalfBoundedRelInterval,
HasEmptiableRelBoundPair,
HasRelBoundPair,
RelBoundPair,
RelEndBound,
RelInterval,
RelStartBound,
};
use crate::intervals::special::{EmptyInterval, UnboundedInterval};
pub trait ShrinkableStartBound<P> {
type Output;
fn shrink_start(&self, position: P) -> Self::Output;
}
pub trait ShrinkableEndBound<P> {
type Output;
fn shrink_end(&self, position: P) -> Self::Output;
}
impl ShrinkableStartBound<AbsStartBound> for AbsBoundPair {
type Output = Self;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
shrink_start_abs_bound_pair(self, position)
}
}
impl ShrinkableEndBound<AbsEndBound> for AbsBoundPair {
type Output = Self;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
shrink_end_abs_bound_pair(self, position)
}
}
impl ShrinkableStartBound<AbsStartBound> for EmptiableAbsBoundPair {
type Output = Self;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
shrink_start_emptiable_abs_bound_pair(self, position)
}
}
impl ShrinkableEndBound<AbsEndBound> for EmptiableAbsBoundPair {
type Output = Self;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
shrink_end_emptiable_abs_bound_pair(self, position)
}
}
impl ShrinkableStartBound<AbsStartBound> for AbsInterval {
type Output = Self;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
Self::Output::from(shrink_start_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableEndBound<AbsEndBound> for AbsInterval {
type Output = Self;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
Self::Output::from(shrink_end_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableStartBound<AbsStartBound> for EmptiableAbsInterval {
type Output = Self;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
Self::Output::from(shrink_start_emptiable_abs_bound_pair(
&self.emptiable_abs_bound_pair(),
position,
))
}
}
impl ShrinkableEndBound<AbsEndBound> for EmptiableAbsInterval {
type Output = Self;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
Self::Output::from(shrink_end_emptiable_abs_bound_pair(
&self.emptiable_abs_bound_pair(),
position,
))
}
}
impl ShrinkableStartBound<AbsStartBound> for BoundedAbsInterval {
type Output = AbsInterval;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
Self::Output::from(shrink_start_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableEndBound<AbsEndBound> for BoundedAbsInterval {
type Output = AbsInterval;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
Self::Output::from(shrink_end_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableStartBound<AbsStartBound> for HalfBoundedAbsInterval {
type Output = AbsInterval;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
Self::Output::from(shrink_start_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableEndBound<AbsEndBound> for HalfBoundedAbsInterval {
type Output = AbsInterval;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
Self::Output::from(shrink_end_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableStartBound<RelStartBound> for RelBoundPair {
type Output = Self;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
shrink_start_rel_bound_pair(self, position)
}
}
impl ShrinkableEndBound<RelEndBound> for RelBoundPair {
type Output = Self;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
shrink_end_rel_bound_pair(self, position)
}
}
impl ShrinkableStartBound<RelStartBound> for EmptiableRelBoundPair {
type Output = Self;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
shrink_start_emptiable_rel_bound_pair(self, position)
}
}
impl ShrinkableEndBound<RelEndBound> for EmptiableRelBoundPair {
type Output = Self;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
shrink_end_emptiable_rel_bound_pair(self, position)
}
}
impl ShrinkableStartBound<RelStartBound> for RelInterval {
type Output = Self;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
Self::Output::from(shrink_start_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableEndBound<RelEndBound> for RelInterval {
type Output = Self;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
Self::Output::from(shrink_end_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableStartBound<RelStartBound> for EmptiableRelInterval {
type Output = Self;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
Self::Output::from(shrink_start_emptiable_rel_bound_pair(
&self.emptiable_rel_bound_pair(),
position,
))
}
}
impl ShrinkableEndBound<RelEndBound> for EmptiableRelInterval {
type Output = Self;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
Self::Output::from(shrink_end_emptiable_rel_bound_pair(
&self.emptiable_rel_bound_pair(),
position,
))
}
}
impl ShrinkableStartBound<RelStartBound> for BoundedRelInterval {
type Output = RelInterval;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
Self::Output::from(shrink_start_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableEndBound<RelEndBound> for BoundedRelInterval {
type Output = RelInterval;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
Self::Output::from(shrink_end_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableStartBound<RelStartBound> for HalfBoundedRelInterval {
type Output = RelInterval;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
Self::Output::from(shrink_start_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableEndBound<RelEndBound> for HalfBoundedRelInterval {
type Output = RelInterval;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
Self::Output::from(shrink_end_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableStartBound<AbsStartBound> for UnboundedInterval {
type Output = AbsInterval;
fn shrink_start(&self, position: AbsStartBound) -> Self::Output {
Self::Output::from(shrink_start_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableEndBound<AbsEndBound> for UnboundedInterval {
type Output = AbsInterval;
fn shrink_end(&self, position: AbsEndBound) -> Self::Output {
Self::Output::from(shrink_end_abs_bound_pair(&self.abs_bound_pair(), position))
}
}
impl ShrinkableStartBound<RelStartBound> for UnboundedInterval {
type Output = RelInterval;
fn shrink_start(&self, position: RelStartBound) -> Self::Output {
Self::Output::from(shrink_start_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableEndBound<RelEndBound> for UnboundedInterval {
type Output = RelInterval;
fn shrink_end(&self, position: RelEndBound) -> Self::Output {
Self::Output::from(shrink_end_rel_bound_pair(&self.rel_bound_pair(), position))
}
}
impl ShrinkableStartBound<AbsStartBound> for EmptyInterval {
type Output = EmptyInterval;
fn shrink_start(&self, _position: AbsStartBound) -> Self::Output {
*self
}
}
impl ShrinkableEndBound<AbsEndBound> for EmptyInterval {
type Output = EmptyInterval;
fn shrink_end(&self, _position: AbsEndBound) -> Self::Output {
*self
}
}
impl ShrinkableStartBound<RelStartBound> for EmptyInterval {
type Output = EmptyInterval;
fn shrink_start(&self, _position: RelStartBound) -> Self::Output {
*self
}
}
impl ShrinkableEndBound<RelEndBound> for EmptyInterval {
type Output = EmptyInterval;
fn shrink_end(&self, _position: RelEndBound) -> Self::Output {
*self
}
}
#[must_use]
pub fn shrink_start_abs_bound_pair(bounds: &AbsBoundPair, at: AbsStartBound) -> AbsBoundPair {
let mut new_bounds = bounds.clone();
let max_start = new_bounds.abs_start().max(at);
if max_start.bound_le(&new_bounds.abs_end(), BoundOverlapDisambiguationRuleSet::Strict) {
new_bounds.set_start(max_start);
}
new_bounds
}
#[must_use]
pub fn shrink_start_emptiable_abs_bound_pair(
emptiable_bounds: &EmptiableAbsBoundPair,
at: AbsStartBound,
) -> EmptiableAbsBoundPair {
let EmptiableAbsBoundPair::Bound(bounds) = emptiable_bounds else {
return emptiable_bounds.clone();
};
EmptiableAbsBoundPair::from(shrink_start_abs_bound_pair(bounds, at))
}
#[must_use]
pub fn shrink_end_abs_bound_pair(bounds: &AbsBoundPair, at: AbsEndBound) -> AbsBoundPair {
let mut new_bounds = bounds.clone();
let min_end = new_bounds.abs_end().min(at);
if new_bounds
.abs_start()
.bound_le(&min_end, BoundOverlapDisambiguationRuleSet::Strict)
{
new_bounds.set_end(min_end);
}
new_bounds
}
#[must_use]
pub fn shrink_end_emptiable_abs_bound_pair(
emptiable_bounds: &EmptiableAbsBoundPair,
at: AbsEndBound,
) -> EmptiableAbsBoundPair {
let EmptiableAbsBoundPair::Bound(bounds) = emptiable_bounds else {
return emptiable_bounds.clone();
};
EmptiableAbsBoundPair::from(shrink_end_abs_bound_pair(bounds, at))
}
#[must_use]
pub fn shrink_start_rel_bound_pair(bounds: &RelBoundPair, at: RelStartBound) -> RelBoundPair {
let mut new_bounds = bounds.clone();
let max_start = new_bounds.rel_start().max(at);
if max_start.bound_le(&new_bounds.rel_end(), BoundOverlapDisambiguationRuleSet::Strict) {
new_bounds.set_start(max_start);
}
new_bounds
}
#[must_use]
pub fn shrink_start_emptiable_rel_bound_pair(
emptiable_bounds: &EmptiableRelBoundPair,
at: RelStartBound,
) -> EmptiableRelBoundPair {
let EmptiableRelBoundPair::Bound(bounds) = emptiable_bounds else {
return emptiable_bounds.clone();
};
EmptiableRelBoundPair::from(shrink_start_rel_bound_pair(bounds, at))
}
#[must_use]
pub fn shrink_end_rel_bound_pair(bounds: &RelBoundPair, at: RelEndBound) -> RelBoundPair {
let mut new_bounds = bounds.clone();
let min_end = new_bounds.rel_end().min(at);
if new_bounds
.rel_start()
.bound_le(&min_end, BoundOverlapDisambiguationRuleSet::Strict)
{
new_bounds.set_end(min_end);
}
new_bounds
}
#[must_use]
pub fn shrink_end_emptiable_rel_bound_pair(
emptiable_bounds: &EmptiableRelBoundPair,
at: RelEndBound,
) -> EmptiableRelBoundPair {
let EmptiableRelBoundPair::Bound(bounds) = emptiable_bounds else {
return emptiable_bounds.clone();
};
EmptiableRelBoundPair::from(shrink_end_rel_bound_pair(bounds, at))
}