#[cfg(feature = "arbitrary")]
use arbitrary::Arbitrary;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::intervals::meta::BoundInclusivity;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum BoundOverlapAmbiguity {
BothStarts(BoundInclusivity, BoundInclusivity),
BothEnds(BoundInclusivity, BoundInclusivity),
StartEnd(BoundInclusivity, BoundInclusivity),
EndStart(BoundInclusivity, BoundInclusivity),
}
impl BoundOverlapAmbiguity {
#[must_use]
pub fn is_both_starts(&self) -> bool {
matches!(self, Self::BothStarts(..))
}
#[must_use]
pub fn is_both_ends(&self) -> bool {
matches!(self, Self::BothEnds(..))
}
#[must_use]
pub fn is_start_end(&self) -> bool {
matches!(self, Self::StartEnd(..))
}
#[must_use]
pub fn is_end_start(&self) -> bool {
matches!(self, Self::EndStart(..))
}
#[must_use]
pub fn swap_reference_and_compared(self) -> Self {
match self {
Self::BothStarts(ref_incl, comp_incl) => Self::BothStarts(comp_incl, ref_incl),
Self::BothEnds(ref_incl, comp_incl) => Self::BothEnds(comp_incl, ref_incl),
Self::StartEnd(ref_incl, comp_incl) => Self::StartEnd(comp_incl, ref_incl),
Self::EndStart(ref_incl, comp_incl) => Self::EndStart(comp_incl, ref_incl),
}
}
#[must_use]
pub fn disambiguate(self, rule_set: BoundOverlapDisambiguationRuleSet) -> DisambiguatedBoundOverlap {
rule_set.disambiguate(self)
}
#[must_use]
pub fn disambiguate_using<F>(self, f: F) -> DisambiguatedBoundOverlap
where
F: FnOnce(Self) -> DisambiguatedBoundOverlap,
{
(f)(self)
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum BoundOverlapDisambiguationRuleSet {
#[default]
Strict,
Lenient,
VeryLenient,
ContinuousToFuture,
ContinuousToPast,
}
impl BoundOverlapDisambiguationRuleSet {
#[must_use]
pub fn disambiguate(&self, ambiguity: BoundOverlapAmbiguity) -> DisambiguatedBoundOverlap {
match self {
Self::Strict => strict_bound_overlap_disambiguation(ambiguity),
Self::Lenient => lenient_bound_overlap_disambiguation(ambiguity),
Self::VeryLenient => very_lenient_bound_overlap_disambiguation(ambiguity),
Self::ContinuousToFuture => continuous_to_future_bound_overlap_disambiguation(ambiguity),
Self::ContinuousToPast => continuous_to_past_bound_overlap_disambiguation(ambiguity),
}
}
}
#[must_use]
pub fn strict_bound_overlap_disambiguation(ambiguity: BoundOverlapAmbiguity) -> DisambiguatedBoundOverlap {
type Boa = BoundOverlapAmbiguity;
type Bi = BoundInclusivity;
match ambiguity {
Boa::BothStarts(Bi::Inclusive, Bi::Exclusive)
| Boa::BothEnds(Bi::Exclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Exclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Inclusive | Bi::Exclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::Before,
Boa::BothStarts(Bi::Inclusive, Bi::Inclusive)
| Boa::BothStarts(Bi::Exclusive, Bi::Exclusive)
| Boa::BothEnds(Bi::Inclusive, Bi::Inclusive)
| Boa::BothEnds(Bi::Exclusive, Bi::Exclusive)
| Boa::StartEnd(Bi::Inclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Inclusive, Bi::Inclusive) => DisambiguatedBoundOverlap::Equal,
Boa::BothStarts(Bi::Exclusive, Bi::Inclusive)
| Boa::BothEnds(Bi::Inclusive, Bi::Exclusive)
| Boa::StartEnd(Bi::Exclusive, Bi::Inclusive)
| Boa::StartEnd(Bi::Inclusive | Bi::Exclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::After,
}
}
#[must_use]
pub fn lenient_bound_overlap_disambiguation(ambiguity: BoundOverlapAmbiguity) -> DisambiguatedBoundOverlap {
type Boa = BoundOverlapAmbiguity;
type Bi = BoundInclusivity;
match ambiguity {
Boa::EndStart(Bi::Exclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::Before,
Boa::BothStarts(Bi::Inclusive | Bi::Exclusive, Bi::Inclusive | Bi::Exclusive)
| Boa::BothEnds(Bi::Inclusive | Bi::Exclusive, Bi::Inclusive | Bi::Exclusive)
| Boa::StartEnd(Bi::Inclusive | Bi::Exclusive, Bi::Inclusive)
| Boa::StartEnd(Bi::Inclusive, Bi::Exclusive)
| Boa::EndStart(Bi::Inclusive | Bi::Exclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Inclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::Equal,
Boa::StartEnd(Bi::Exclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::After,
}
}
#[must_use]
pub fn very_lenient_bound_overlap_disambiguation(_ambiguity: BoundOverlapAmbiguity) -> DisambiguatedBoundOverlap {
DisambiguatedBoundOverlap::Equal
}
#[must_use]
pub fn continuous_to_future_bound_overlap_disambiguation(
ambiguity: BoundOverlapAmbiguity,
) -> DisambiguatedBoundOverlap {
type Boa = BoundOverlapAmbiguity;
type Bi = BoundInclusivity;
match ambiguity {
Boa::BothStarts(Bi::Inclusive, Bi::Exclusive)
| Boa::BothEnds(Bi::Exclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Inclusive | Bi::Exclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::Before,
Boa::BothStarts(Bi::Inclusive, Bi::Inclusive)
| Boa::BothStarts(Bi::Exclusive, Bi::Exclusive)
| Boa::BothEnds(Bi::Inclusive, Bi::Inclusive)
| Boa::BothEnds(Bi::Exclusive, Bi::Exclusive)
| Boa::StartEnd(Bi::Inclusive, Bi::Inclusive | Bi::Exclusive)
| Boa::EndStart(Bi::Inclusive | Bi::Exclusive, Bi::Inclusive) => DisambiguatedBoundOverlap::Equal,
Boa::BothStarts(Bi::Exclusive, Bi::Inclusive)
| Boa::BothEnds(Bi::Inclusive, Bi::Exclusive)
| Boa::StartEnd(Bi::Exclusive, Bi::Inclusive | Bi::Exclusive) => DisambiguatedBoundOverlap::After,
}
}
#[must_use]
pub fn continuous_to_past_bound_overlap_disambiguation(ambiguity: BoundOverlapAmbiguity) -> DisambiguatedBoundOverlap {
type Boa = BoundOverlapAmbiguity;
type Bi = BoundInclusivity;
match ambiguity {
Boa::BothStarts(Bi::Inclusive, Bi::Exclusive)
| Boa::BothEnds(Bi::Exclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Exclusive, Bi::Inclusive | Bi::Exclusive) => DisambiguatedBoundOverlap::Before,
Boa::BothStarts(Bi::Inclusive, Bi::Inclusive)
| Boa::BothStarts(Bi::Exclusive, Bi::Exclusive)
| Boa::BothEnds(Bi::Inclusive, Bi::Inclusive)
| Boa::BothEnds(Bi::Exclusive, Bi::Exclusive)
| Boa::StartEnd(Bi::Inclusive | Bi::Exclusive, Bi::Inclusive)
| Boa::EndStart(Bi::Inclusive, Bi::Inclusive | Bi::Exclusive) => DisambiguatedBoundOverlap::Equal,
Boa::BothStarts(Bi::Exclusive, Bi::Inclusive)
| Boa::BothEnds(Bi::Inclusive, Bi::Exclusive)
| Boa::StartEnd(Bi::Inclusive | Bi::Exclusive, Bi::Exclusive) => DisambiguatedBoundOverlap::After,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
pub enum DisambiguatedBoundOverlap {
Before,
Equal,
After,
}
impl DisambiguatedBoundOverlap {
#[must_use]
pub fn is_before(&self) -> bool {
matches!(self, Self::Before)
}
#[must_use]
pub fn is_equal(&self) -> bool {
matches!(self, Self::Equal)
}
#[must_use]
pub fn is_after(&self) -> bool {
matches!(self, Self::After)
}
#[must_use]
pub fn is_before_or_equal(&self) -> bool {
matches!(self, Self::Before | Self::Equal)
}
#[must_use]
pub fn is_after_or_equal(&self) -> bool {
matches!(self, Self::After | Self::Equal)
}
}