use core::cmp::Ordering;
use core::ops::{Bound, RangeBounds};
use crate::{Domain, GenericRange};
#[allow(clippy::missing_inline_in_public_items, clippy::exhaustive_enums)]
#[derive(Debug, PartialEq, Eq)]
pub enum Relation<T: Domain> {
Disjoint {
first: GenericRange<T>,
second: GenericRange<T>,
self_less: bool,
},
Touching {
first: GenericRange<T>,
second: GenericRange<T>,
self_less: bool,
},
Overlapping {
first_disjoint: GenericRange<T>,
second_disjoint: GenericRange<T>,
overlap: GenericRange<T>,
self_less: bool,
overlap_is_singleton: bool,
},
Containing {
first_disjoint: GenericRange<T>,
second_disjoint: GenericRange<T>,
overlap: GenericRange<T>,
self_shorter: bool,
},
Starting {
overlap: GenericRange<T>,
disjoint: GenericRange<T>,
self_shorter: bool,
shorter_is_singleton: bool,
},
Ending {
disjoint: GenericRange<T>,
overlap: GenericRange<T>,
self_shorter: bool,
shorter_is_singleton: bool,
},
Equal(GenericRange<T>),
Empty {
non_empty: Option<GenericRange<T>>,
self_empty: Option<bool>,
},
}
#[allow(clippy::missing_inline_in_public_items, clippy::exhaustive_enums)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Arrangement {
Disjoint {
self_less: bool,
},
Touching {
self_less: bool,
},
Overlapping {
self_less: bool,
overlap_is_singleton: bool,
},
Containing {
self_shorter: bool,
},
Starting {
self_shorter: bool,
shorter_is_singleton: bool,
},
Ending {
self_shorter: bool,
shorter_is_singleton: bool,
},
Equal,
Empty {
self_empty: Option<bool>,
},
}
impl<T> GenericRange<T> {
#[must_use]
pub fn cmp_start_start(start: Bound<&T>, other_start: Bound<&T>) -> Ordering
where
T: Domain,
{
match (start, other_start) {
(Bound::Unbounded, Bound::Unbounded) => Ordering::Equal,
(Bound::Unbounded, _) => Ordering::Less,
(_, Bound::Unbounded) => Ordering::Greater,
(Bound::Included(a), Bound::Included(b)) | (Bound::Excluded(a), Bound::Excluded(b)) => a.cmp(b),
(Bound::Included(a), Bound::Excluded(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Greater => {
if a.is_next_to(b) {
Ordering::Equal
} else {
Ordering::Greater
}
}
Ordering::Equal | Ordering::Less => Ordering::Less,
}
} else {
match a.cmp(b) {
Ordering::Greater => Ordering::Greater,
Ordering::Equal | Ordering::Less => Ordering::Less,
}
}
}
(Bound::Excluded(a), Bound::Included(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Less => {
if a.is_next_to(b) {
Ordering::Equal
} else {
Ordering::Less
}
}
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
} else {
match a.cmp(b) {
Ordering::Less => Ordering::Less,
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
}
}
}
}
#[must_use]
pub fn cmp_start_end(start: Bound<&T>, end: Bound<&T>) -> Ordering
where
T: Domain,
{
match (start, end) {
(Bound::Unbounded, _) | (_, Bound::Unbounded) => Ordering::Less,
(Bound::Included(a), Bound::Included(b)) => a.cmp(b),
(Bound::Excluded(a), Bound::Excluded(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Less => {
if a.is_next_to(b) {
Ordering::Greater
} else if a.shares_neighbour_with(b) {
Ordering::Equal
} else {
Ordering::Less
}
}
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
} else {
match a.cmp(b) {
Ordering::Less => Ordering::Less,
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
}
}
(Bound::Included(a), Bound::Excluded(b)) | (Bound::Excluded(a), Bound::Included(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Less => {
if a.is_next_to(b) {
Ordering::Equal
} else {
Ordering::Less
}
}
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
} else {
match a.cmp(b) {
Ordering::Greater | Ordering::Equal => Ordering::Greater,
Ordering::Less => Ordering::Less,
}
}
}
}
}
#[must_use]
pub fn cmp_end_start(end: Bound<&T>, start: Bound<&T>) -> Ordering
where
T: Domain,
{
match (end, start) {
(Bound::Unbounded, _) | (_, Bound::Unbounded) => Ordering::Greater,
(Bound::Included(a), Bound::Included(b)) => a.cmp(b),
(Bound::Excluded(a), Bound::Excluded(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Greater => {
if a.is_next_to(b) {
Ordering::Less
} else if a.shares_neighbour_with(b) {
Ordering::Equal
} else {
Ordering::Greater
}
}
Ordering::Equal | Ordering::Less => Ordering::Less,
}
} else {
match a.cmp(b) {
Ordering::Greater => Ordering::Greater,
Ordering::Equal | Ordering::Less => Ordering::Less,
}
}
}
(Bound::Included(a), Bound::Excluded(b)) | (Bound::Excluded(a), Bound::Included(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Greater => {
if a.is_next_to(b) {
Ordering::Equal
} else {
Ordering::Greater
}
}
Ordering::Equal | Ordering::Less => Ordering::Less,
}
} else {
match a.cmp(b) {
Ordering::Less | Ordering::Equal => Ordering::Less,
Ordering::Greater => Ordering::Greater,
}
}
}
}
}
#[must_use]
pub fn cmp_end_end(end: Bound<&T>, other_end: Bound<&T>) -> Ordering
where
T: Domain,
{
match (end, other_end) {
(Bound::Unbounded, Bound::Unbounded) => Ordering::Equal,
(Bound::Unbounded, _) => Ordering::Greater,
(_, Bound::Unbounded) => Ordering::Less,
(Bound::Included(a), Bound::Included(b)) | (Bound::Excluded(a), Bound::Excluded(b)) => a.cmp(b),
(Bound::Included(a), Bound::Excluded(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Less => {
if a.is_next_to(b) {
Ordering::Equal
} else {
Ordering::Less
}
}
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
} else {
match a.cmp(b) {
Ordering::Less => Ordering::Less,
Ordering::Equal | Ordering::Greater => Ordering::Greater,
}
}
}
(Bound::Excluded(a), Bound::Included(b)) => {
if <T as Domain>::DISCRETE {
match a.cmp(b) {
Ordering::Greater => {
if a.is_next_to(b) {
Ordering::Equal
} else {
Ordering::Greater
}
}
Ordering::Equal | Ordering::Less => Ordering::Less,
}
} else {
match a.cmp(b) {
Ordering::Greater => Ordering::Greater,
Ordering::Equal | Ordering::Less => Ordering::Less,
}
}
}
}
}
#[must_use]
pub fn is_bound_touching(bound: Bound<&T>, other: Bound<&T>) -> bool
where
T: PartialEq,
{
match (bound, other) {
(Bound::Excluded(x), Bound::Included(y)) | (Bound::Included(x), Bound::Excluded(y)) => x == y,
_ => false,
}
}
#[must_use]
pub fn is_disjoint(&self, other: &Self) -> bool
where
T: Domain,
{
if self.is_empty() || other.is_empty() {
return true;
}
let end_start = Self::cmp_end_start(self.end_bound(), other.start_bound());
let end_start_touching = Self::is_bound_touching(self.end_bound(), other.start_bound());
let start_end = Self::cmp_start_end(self.start_bound(), other.end_bound());
let start_end_touching = Self::is_bound_touching(self.start_bound(), other.end_bound());
(end_start == Ordering::Less && !end_start_touching) || (start_end == Ordering::Greater && !start_end_touching)
}
#[must_use]
pub fn is_touching(&self, other: &Self) -> bool
where
T: PartialEq + Domain,
{
if self.is_empty() || other.is_empty() {
return false;
}
Self::is_bound_touching(self.end_bound(), other.start_bound())
|| Self::is_bound_touching(self.start_bound(), other.end_bound())
}
#[must_use]
pub fn is_overlapping(&self, other: &Self) -> bool
where
T: Domain,
{
let start_start = Self::cmp_start_start(self.start_bound(), other.start_bound());
match start_start {
Ordering::Equal => false,
Ordering::Less => {
let end_start = Self::cmp_end_start(self.end_bound(), other.start_bound());
if end_start == Ordering::Less
|| (end_start == Ordering::Equal && Self::is_bound_touching(self.end_bound(), other.start_bound()))
{
return false;
}
let end_end = Self::cmp_end_end(other.end_bound(), self.end_bound());
end_end == Ordering::Greater
}
Ordering::Greater => {
let end_start = Self::cmp_end_start(other.end_bound(), self.start_bound());
if end_start == Ordering::Less
|| (end_start == Ordering::Equal && Self::is_bound_touching(other.end_bound(), self.start_bound()))
{
return false;
}
let end_end = Self::cmp_end_end(self.end_bound(), other.end_bound());
end_end == Ordering::Greater
}
}
}
#[must_use]
pub fn is_containing(&self, other: &Self) -> bool
where
T: Domain,
{
if other.is_empty() {
return true;
}
Self::cmp_start_start(other.start_bound(), self.start_bound()) == Ordering::Greater
&& Self::cmp_end_end(other.end_bound(), self.end_bound()) == Ordering::Less
}
#[must_use]
pub fn is_contained_by(&self, other: &Self) -> bool
where
T: Domain,
{
if self.is_empty() {
return true;
}
Self::cmp_start_start(self.start_bound(), other.start_bound()) == Ordering::Greater
&& Self::cmp_end_end(self.end_bound(), other.end_bound()) == Ordering::Less
}
#[must_use]
pub fn is_starting_with(&self, other: &Self) -> bool
where
T: Domain,
{
if self.is_empty() || other.is_empty() {
return false;
}
Self::cmp_start_start(self.start_bound(), other.start_bound()) == Ordering::Equal
&& Self::cmp_end_end(self.end_bound(), other.end_bound()) != Ordering::Equal
}
#[must_use]
pub fn is_ending_with(&self, other: &Self) -> bool
where
T: Domain,
{
if self.is_empty() || other.is_empty() {
return false;
}
Self::cmp_start_start(self.start_bound(), other.start_bound()) != Ordering::Equal
&& Self::cmp_end_end(self.end_bound(), other.end_bound()) == Ordering::Equal
}
#[must_use]
pub fn is_equal(&self, other: &Self) -> bool
where
T: Domain,
{
Self::cmp_start_start(other.start_bound(), self.start_bound()) == Ordering::Equal
&& Self::cmp_end_end(other.end_bound(), self.end_bound()) == Ordering::Equal
}
#[must_use]
pub fn relation(self, other: Self) -> Relation<T>
where
T: Clone + Domain,
{
match self.arrangement(&other) {
Arrangement::Disjoint { self_less } => {
let (first, second) = if self_less { (self, other) } else { (other, self) };
Relation::Disjoint {
first,
second,
self_less,
}
}
Arrangement::Touching { self_less } => {
let (first, second) = if self_less { (self, other) } else { (other, self) };
Relation::Touching {
first,
second,
self_less,
}
}
Arrangement::Overlapping {
self_less,
overlap_is_singleton,
} => {
let (first, second) = if self_less { (self, other) } else { (other, self) };
let first_disjoint_end = Self::invert_border_cloned(&second.start);
let second_disjoint_start = Self::invert_border_cloned(&first.end);
let first_disjoint = (first.start, first_disjoint_end).into();
let second_disjoint = (second_disjoint_start, second.end).into();
Relation::Overlapping {
first_disjoint,
second_disjoint,
overlap: (second.start, first.end).into(),
self_less,
overlap_is_singleton,
}
}
Arrangement::Containing { self_shorter } => {
let (bigger, smaller) = if self_shorter { (other, self) } else { (self, other) };
let first_end = Self::invert_border_cloned(&smaller.start);
let second_start = Self::invert_border_cloned(&smaller.end);
Relation::Containing {
first_disjoint: (bigger.start, first_end).into(),
second_disjoint: (second_start, bigger.end).into(),
overlap: smaller,
self_shorter,
}
}
Arrangement::Starting {
self_shorter,
shorter_is_singleton,
} => {
let (longer, shorter) = if self_shorter { (other, self) } else { (self, other) };
let disjoint_start = Self::invert_border_cloned(&shorter.end);
Relation::Starting {
overlap: shorter,
disjoint: (disjoint_start, longer.end).into(),
self_shorter,
shorter_is_singleton,
}
}
Arrangement::Ending {
self_shorter,
shorter_is_singleton,
} => {
let (longer, shorter) = if self_shorter { (other, self) } else { (self, other) };
let disjoint_end = Self::invert_border_cloned(&shorter.start);
Relation::Ending {
overlap: shorter,
disjoint: (longer.start, disjoint_end).into(),
self_shorter,
shorter_is_singleton,
}
}
Arrangement::Equal => Relation::Equal(self),
Arrangement::Empty { self_empty } => Relation::Empty {
non_empty: self_empty.map(|empty| if empty { other } else { self }),
self_empty,
},
}
}
#[allow(clippy::too_many_lines)]
#[must_use]
pub fn arrangement(&self, other: &Self) -> Arrangement
where
T: Domain,
{
match (self.is_empty(), other.is_empty()) {
(true, true) => return Arrangement::Empty { self_empty: None },
(true, false) => return Arrangement::Empty { self_empty: Some(true) },
(false, true) => {
return Arrangement::Empty {
self_empty: Some(false),
}
}
(false, false) => (),
}
let (self_start, self_end) = (self.start_bound(), self.end_bound());
let (other_start, other_end) = (other.start_bound(), other.end_bound());
let start_end = Self::cmp_start_end(self_start, other_end);
let end_start = Self::cmp_end_start(self_end, other_start);
let start_start = Self::cmp_start_start(self_start, other_start);
let end_end = Self::cmp_end_end(self_end, other_end);
match (start_end, end_start, start_start, end_end) {
(Ordering::Less, Ordering::Less, Ordering::Less, Ordering::Less) => {
if Self::is_bound_touching(self_end, other_start) {
Arrangement::Touching { self_less: true }
} else {
Arrangement::Disjoint { self_less: true }
}
}
(Ordering::Greater, Ordering::Greater, Ordering::Greater, Ordering::Greater) => {
if Self::is_bound_touching(other_end, self_start) {
Arrangement::Touching { self_less: false }
} else {
Arrangement::Disjoint { self_less: false }
}
}
(Ordering::Less, Ordering::Greater, Ordering::Less, Ordering::Less) => Arrangement::Overlapping {
self_less: true,
overlap_is_singleton: false,
},
(Ordering::Less, Ordering::Greater, Ordering::Greater, Ordering::Greater) => Arrangement::Overlapping {
self_less: false,
overlap_is_singleton: false,
},
(Ordering::Less, Ordering::Equal, Ordering::Less, Ordering::Less) => Arrangement::Overlapping {
self_less: true,
overlap_is_singleton: true,
},
(Ordering::Equal, Ordering::Greater, Ordering::Greater, Ordering::Greater) => Arrangement::Overlapping {
self_less: false,
overlap_is_singleton: true,
},
(Ordering::Less, Ordering::Greater, Ordering::Less, Ordering::Greater) => {
Arrangement::Containing { self_shorter: false }
}
(Ordering::Less, Ordering::Greater, Ordering::Greater, Ordering::Less) => {
Arrangement::Containing { self_shorter: true }
}
(Ordering::Less, Ordering::Greater, Ordering::Equal, Ordering::Less) => Arrangement::Starting {
self_shorter: true,
shorter_is_singleton: false,
},
(Ordering::Less, Ordering::Greater, Ordering::Equal, Ordering::Greater) => Arrangement::Starting {
self_shorter: false,
shorter_is_singleton: false,
},
(Ordering::Less, Ordering::Equal, Ordering::Equal, Ordering::Less) => Arrangement::Starting {
self_shorter: true,
shorter_is_singleton: true,
},
(Ordering::Equal, Ordering::Greater, Ordering::Equal, Ordering::Greater) => Arrangement::Starting {
self_shorter: false,
shorter_is_singleton: true,
},
(Ordering::Less, Ordering::Greater, Ordering::Less, Ordering::Equal) => Arrangement::Ending {
self_shorter: false,
shorter_is_singleton: false,
},
(Ordering::Less, Ordering::Greater, Ordering::Greater, Ordering::Equal) => Arrangement::Ending {
self_shorter: true,
shorter_is_singleton: false,
},
(Ordering::Less, Ordering::Equal, Ordering::Less, Ordering::Equal) => Arrangement::Ending {
self_shorter: false,
shorter_is_singleton: true,
},
(Ordering::Equal, Ordering::Greater, Ordering::Greater, Ordering::Equal) => Arrangement::Ending {
self_shorter: true,
shorter_is_singleton: true,
},
(Ordering::Less, Ordering::Greater, Ordering::Equal, Ordering::Equal)
| (Ordering::Equal, Ordering::Equal, Ordering::Equal, Ordering::Equal) => Arrangement::Equal,
_ => unreachable!(
"start_end: {:?}, end_start: {:?}, start_start: {:?}, end_end: {:?}",
start_end, end_start, start_start, end_end
),
}
}
}
#[cfg(test)]
mod tests_discrete {
use core::cmp::Ordering;
use core::ops::Bound;
use proptest::prelude::*;
use crate::{Arrangement, GenericRange, Relation};
#[test]
fn ordering_start_start_unbounded() {
assert_eq!(
GenericRange::cmp_start_start(Bound::<&usize>::Unbounded, Bound::Unbounded),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Unbounded, Bound::Included(&5)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&5), Bound::Unbounded),
Ordering::Greater
);
}
#[test]
fn ordering_start_start_same() {
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&42), Bound::Included(&42)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&7), Bound::Included(&42)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&42), Bound::Included(&7)),
Ordering::Greater
);
}
#[test]
fn ordering_start_start_in_ex() {
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&0), Bound::Excluded(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&2), Bound::Excluded(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&3), Bound::Excluded(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&4), Bound::Excluded(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_start_start_ex_in() {
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&0), Bound::Included(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&1), Bound::Included(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&2), Bound::Included(&2)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&3), Bound::Included(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_end_end_unbounded() {
assert_eq!(
GenericRange::cmp_end_end(Bound::<&usize>::Unbounded, Bound::Unbounded),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Unbounded, Bound::Included(&5)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&5), Bound::Unbounded),
Ordering::Less
);
}
#[test]
fn ordering_end_end_same() {
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&42), Bound::Included(&42)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&7), Bound::Included(&42)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&42), Bound::Included(&7)),
Ordering::Greater
);
}
#[test]
fn ordering_end_end_in_ex() {
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&0), Bound::Excluded(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&1), Bound::Excluded(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&2), Bound::Excluded(&2)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&3), Bound::Excluded(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_end_end_ex_in() {
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&0), Bound::Included(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&2), Bound::Included(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&3), Bound::Included(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&4), Bound::Included(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_unbounded() {
assert_eq!(
GenericRange::cmp_start_end(Bound::<&usize>::Unbounded, Bound::Unbounded),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Unbounded, Bound::Included(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&3), Bound::Unbounded),
Ordering::Less
);
}
#[test]
fn ordering_start_end_same_in() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&2), Bound::Included(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&3), Bound::Included(&3)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&4), Bound::Included(&3)),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_same_ex() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&0), Bound::Excluded(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&1), Bound::Excluded(&3)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&2), Bound::Excluded(&3)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&3), Bound::Excluded(&3)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&4), Bound::Excluded(&3)),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_in_ex() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&0), Bound::Excluded(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&1), Bound::Excluded(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&2), Bound::Excluded(&2)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&3), Bound::Excluded(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_ex_in() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&0), Bound::Included(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&1), Bound::Included(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&2), Bound::Included(&2)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&3), Bound::Included(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_unbounded() {
assert_eq!(
GenericRange::cmp_end_start(Bound::<&usize>::Unbounded, Bound::Unbounded),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Unbounded, Bound::Included(&3)),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&3), Bound::Unbounded),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_same_in() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&2), Bound::Included(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&3), Bound::Included(&3)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&4), Bound::Included(&3)),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_same_ex() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&2), Bound::Excluded(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&3), Bound::Excluded(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&4), Bound::Excluded(&3)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&5), Bound::Excluded(&3)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&6), Bound::Excluded(&3)),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_in_ex() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&2), Bound::Excluded(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&3), Bound::Excluded(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&4), Bound::Excluded(&2)),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_ex_in() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&2), Bound::Included(&2)),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&3), Bound::Included(&2)),
Ordering::Equal
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&4), Bound::Included(&2)),
Ordering::Greater
);
}
#[test]
fn range_disjoint_range() {
let range = GenericRange::from(0..4);
let range2 = GenericRange::from(5..10);
assert!(range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Disjoint {
first: range,
second: range2,
self_less: true
}
);
assert_eq!(
range2.relation(range),
Relation::Disjoint {
first: range,
second: range2,
self_less: false
}
)
}
#[test]
fn range_disjoint_singleton() {
let range = GenericRange::from(3..9);
let singleton = GenericRange::singleton(10);
assert!(range.is_disjoint(&singleton));
assert!(!range.is_touching(&singleton));
assert!(!range.is_overlapping(&singleton));
assert!(!range.is_containing(&singleton));
assert!(!range.is_contained_by(&singleton));
assert!(!range.is_starting_with(&singleton));
assert!(!range.is_ending_with(&singleton));
assert!(!range.is_equal(&singleton));
assert_eq!(
range.relation(singleton),
Relation::Disjoint {
first: range,
second: singleton,
self_less: true
}
);
}
#[test]
fn singleton_disjoint_range() {
let singleton = GenericRange::singleton(1);
let range = GenericRange::from(2..5);
assert!(singleton.is_disjoint(&range));
assert!(!singleton.is_touching(&range));
assert!(!singleton.is_overlapping(&range));
assert!(!singleton.is_containing(&range));
assert!(!singleton.is_contained_by(&range));
assert!(!singleton.is_starting_with(&range));
assert!(!singleton.is_ending_with(&range));
assert!(!singleton.is_equal(&range));
assert_eq!(
singleton.relation(range),
Relation::Disjoint {
first: singleton,
second: range,
self_less: true
}
)
}
#[test]
fn range_touching_range() {
let range = GenericRange::from(0..5);
let range2 = GenericRange::from(5..10);
assert!(!range.is_disjoint(&range2));
assert!(range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Touching {
first: range,
second: range2,
self_less: true
}
);
}
#[test]
fn range_touching_singleton() {
let range = GenericRange::from(3..10);
let singleton = GenericRange::singleton(10);
assert!(!range.is_disjoint(&singleton));
assert!(range.is_touching(&singleton));
assert!(!range.is_overlapping(&singleton));
assert!(!range.is_containing(&singleton));
assert!(!range.is_contained_by(&singleton));
assert!(!range.is_starting_with(&singleton));
assert!(!range.is_ending_with(&singleton));
assert!(!range.is_equal(&singleton));
assert_eq!(
range.relation(singleton),
Relation::Touching {
first: range,
second: singleton,
self_less: true
}
)
}
#[test]
fn singleton_touching_range() {
let singleton = GenericRange::singleton(3);
let range = GenericRange::new_open_closed(3, 10);
assert!(!singleton.is_disjoint(&range));
assert!(singleton.is_touching(&range));
assert!(!singleton.is_overlapping(&range));
assert!(!singleton.is_containing(&range));
assert!(!singleton.is_contained_by(&range));
assert!(!singleton.is_starting_with(&range));
assert!(!singleton.is_ending_with(&range));
assert!(!singleton.is_equal(&range));
assert_eq!(
range.relation(singleton),
Relation::Touching {
first: singleton,
second: range,
self_less: false
}
)
}
#[test]
fn range_overlapping_range() {
let range = GenericRange::from(0..=10);
let range2 = GenericRange::from(5..=15);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Overlapping {
first_disjoint: GenericRange::from(0..5),
second_disjoint: GenericRange::new_open_closed(10, 15),
overlap: GenericRange::from(5..=10),
self_less: true,
overlap_is_singleton: false
}
);
assert_eq!(
range2.relation(range),
Relation::Overlapping {
first_disjoint: GenericRange::from(0..5),
second_disjoint: GenericRange::new_open_closed(10, 15),
overlap: GenericRange::from(5..=10),
self_less: false,
overlap_is_singleton: false
}
)
}
#[test]
fn range_overlap_range_one_element() {
let range = GenericRange::from(0..=5);
let range2 = GenericRange::from(5..10);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Overlapping {
first_disjoint: GenericRange::from(0..5),
second_disjoint: GenericRange::new_open(5, 10),
overlap: GenericRange::singleton(5),
self_less: true,
overlap_is_singleton: true
}
);
}
#[test]
fn range_overlap_range_one_element_reverse() {
let range = GenericRange::from(5..10);
let range2 = GenericRange::from(0..=5);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Overlapping {
first_disjoint: GenericRange::from(0..5),
second_disjoint: GenericRange::new_open(5, 10),
overlap: GenericRange::singleton(5),
self_less: false,
overlap_is_singleton: true
}
);
}
#[test]
fn range_contains_singleton() {
let range = GenericRange::from(0..=5);
let singleton = GenericRange::singleton(3);
assert!(!range.is_disjoint(&singleton));
assert!(!range.is_touching(&singleton));
assert!(!range.is_overlapping(&singleton));
assert!(range.is_containing(&singleton));
assert!(!range.is_contained_by(&singleton));
assert!(!range.is_starting_with(&singleton));
assert!(!range.is_ending_with(&singleton));
assert!(!range.is_equal(&singleton));
assert_eq!(
range.relation(singleton),
Relation::Containing {
first_disjoint: GenericRange::from(0..3),
second_disjoint: GenericRange::new_open_closed(3, 5),
overlap: singleton,
self_shorter: false
}
)
}
#[test]
fn singleton_contained_in_range() {
let singleton = GenericRange::singleton(3);
let range = GenericRange::from(0..=5);
assert!(!singleton.is_disjoint(&range));
assert!(!singleton.is_touching(&range));
assert!(!singleton.is_overlapping(&range));
assert!(!singleton.is_containing(&range));
assert!(singleton.is_contained_by(&range));
assert!(!singleton.is_starting_with(&range));
assert!(!singleton.is_ending_with(&range));
assert!(!singleton.is_equal(&range));
assert_eq!(
singleton.relation(range),
Relation::Containing {
first_disjoint: GenericRange::from(0..3),
second_disjoint: GenericRange::new_open_closed(3, 5),
overlap: singleton,
self_shorter: true
}
)
}
#[test]
fn range_contains_range() {
let range = GenericRange::from(0..=5);
let range2 = GenericRange::from(1..3);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Containing {
first_disjoint: GenericRange::from(0..1),
second_disjoint: GenericRange::from(3..=5),
overlap: range2,
self_shorter: false
}
)
}
#[test]
fn range_contained_in_range() {
let range = GenericRange::from(1..3);
let range2 = GenericRange::from(0..=5);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Containing {
first_disjoint: GenericRange::from(0..1),
second_disjoint: GenericRange::from(3..=5),
overlap: range,
self_shorter: true
}
)
}
#[test]
fn range_starts_with_longer_range() {
let range = GenericRange::from(0..=5);
let range2 = GenericRange::from(0..10);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Starting {
overlap: range,
disjoint: GenericRange::new_open(5, 10),
self_shorter: true,
shorter_is_singleton: false
}
)
}
#[test]
fn range_starts_with_shorter_range() {
let range = GenericRange::from(0..=5);
let range2 = GenericRange::from(0..3);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Starting {
overlap: range2,
disjoint: GenericRange::from(3..=5),
self_shorter: false,
shorter_is_singleton: false
}
)
}
#[test]
fn range_starts_with_singleton() {
let range = GenericRange::from(0..=5);
let singleton = GenericRange::singleton(0);
assert!(!range.is_disjoint(&singleton));
assert!(!range.is_touching(&singleton));
assert!(!range.is_overlapping(&singleton));
assert!(!range.is_containing(&singleton));
assert!(!range.is_contained_by(&singleton));
assert!(range.is_starting_with(&singleton));
assert!(!range.is_ending_with(&singleton));
assert!(!range.is_equal(&singleton));
assert_eq!(
range.relation(singleton),
Relation::Starting {
overlap: singleton,
disjoint: GenericRange::new_open_closed(0, 5),
self_shorter: false,
shorter_is_singleton: true
}
)
}
#[test]
fn singleton_starting_in_range() {
let singleton = GenericRange::singleton(0);
let range = GenericRange::from(0..=5);
assert!(!singleton.is_disjoint(&range));
assert!(!singleton.is_touching(&range));
assert!(!singleton.is_overlapping(&range));
assert!(!singleton.is_containing(&range));
assert!(!singleton.is_contained_by(&range));
assert!(singleton.is_starting_with(&range));
assert!(!singleton.is_ending_with(&range));
assert!(!singleton.is_equal(&range));
assert_eq!(
singleton.relation(range),
Relation::Starting {
overlap: singleton,
disjoint: GenericRange::new_open_closed(0, 5),
self_shorter: true,
shorter_is_singleton: true
}
)
}
#[test]
fn range_ends_with_shorter_range() {
let range = GenericRange::from(0..10);
let range2 = GenericRange::from(5..=9);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Ending {
disjoint: GenericRange::from(0..5),
overlap: GenericRange::from(5..=9),
self_shorter: false,
shorter_is_singleton: false
}
)
}
#[test]
fn range_ends_with_longer_range() {
let range = GenericRange::from(0..=5);
let range2 = GenericRange::from(-5..6);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(range.is_ending_with(&range2));
assert!(!range.is_equal(&range2));
assert_eq!(
range.relation(range2),
Relation::Ending {
disjoint: GenericRange::from(-5..0),
overlap: GenericRange::from(0..=5),
self_shorter: true,
shorter_is_singleton: false
}
)
}
#[test]
fn range_ends_with_singleton() {
let range = GenericRange::from(0..=5);
let singleton = GenericRange::singleton(5);
assert!(!range.is_disjoint(&singleton));
assert!(!range.is_touching(&singleton));
assert!(!range.is_overlapping(&singleton));
assert!(!range.is_containing(&singleton));
assert!(!range.is_contained_by(&singleton));
assert!(!range.is_starting_with(&singleton));
assert!(range.is_ending_with(&singleton));
assert!(!range.is_equal(&singleton));
assert_eq!(
range.relation(singleton),
Relation::Ending {
disjoint: GenericRange::from(0..5),
overlap: singleton,
self_shorter: false,
shorter_is_singleton: true
}
)
}
#[test]
fn singleton_ends_with_range() {
let singleton = GenericRange::singleton(5);
let range = GenericRange::from(0..=5);
assert!(!singleton.is_disjoint(&range));
assert!(!singleton.is_touching(&range));
assert!(!singleton.is_overlapping(&range));
assert!(!singleton.is_containing(&range));
assert!(!singleton.is_contained_by(&range));
assert!(!singleton.is_starting_with(&range));
assert!(singleton.is_ending_with(&range));
assert!(!singleton.is_equal(&range));
assert_eq!(
singleton.relation(range),
Relation::Ending {
disjoint: GenericRange::from(0..5),
overlap: singleton,
self_shorter: true,
shorter_is_singleton: true
}
)
}
#[test]
fn ranges_are_equal() {
let range = GenericRange::from(0..=5);
let range2 = GenericRange::from(0..6);
assert!(!range.is_disjoint(&range2));
assert!(!range.is_touching(&range2));
assert!(!range.is_overlapping(&range2));
assert!(!range.is_containing(&range2));
assert!(!range.is_contained_by(&range2));
assert!(!range.is_starting_with(&range2));
assert!(!range.is_ending_with(&range2));
assert!(range.is_equal(&range2));
assert_eq!(range.relation(range2), Relation::Equal(range))
}
#[test]
fn singletons_are_equal() {
let singleton = GenericRange::singleton(3);
let singleton2 = GenericRange::singleton(3);
assert!(!singleton.is_disjoint(&singleton2));
assert!(!singleton.is_touching(&singleton2));
assert!(!singleton.is_overlapping(&singleton2));
assert!(!singleton.is_containing(&singleton2));
assert!(!singleton.is_contained_by(&singleton2));
assert!(!singleton.is_starting_with(&singleton2));
assert!(!singleton.is_ending_with(&singleton2));
assert!(singleton.is_equal(&singleton2));
assert_eq!(singleton.relation(singleton2), Relation::Equal(singleton))
}
#[test]
fn equality() {
assert_eq!(GenericRange::from(1..3), GenericRange::from(1..3));
assert_eq!(GenericRange::from(1..=3), GenericRange::from(1..=3));
assert_eq!(GenericRange::from(1..3), GenericRange::from(1..=2));
assert_eq!(GenericRange::new_open_closed(1, 3), GenericRange::from(2..=3));
assert_eq!(GenericRange::new_open(0, 5), GenericRange::from(1..=4));
}
proptest! {
#[ignore]
#[test]
fn verify_is_methods(range in any::<GenericRange<u8>>(), range2 in any::<GenericRange<u8>>()) {
let arrangement = range.arrangement(&range2);
match arrangement {
Arrangement::Disjoint {..} => {
prop_assert!(range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
prop_assert!(!range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Touching {..} => {
prop_assert!(!range.is_disjoint(&range2));
prop_assert!(range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
prop_assert!(!range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Overlapping {..} => {
prop_assert!(!range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(range.is_overlapping(&range2));
prop_assert!(!range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Containing { self_shorter } => {
prop_assert!(!range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
if self_shorter {
prop_assert!(!range.is_containing(&range2));
prop_assert!(range.is_contained_by(&range2));
} else {
prop_assert!(range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
}
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Starting {..} => {
prop_assert!(!range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
prop_assert!(!range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Ending {..} => {
prop_assert!(!range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
prop_assert!(!range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Equal {..} => {
prop_assert!(!range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
prop_assert!(!range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(range.is_equal(&range2));
prop_assert!(!range.is_empty());
prop_assert!(!range2.is_empty());
},
Arrangement::Empty { self_empty } => {
prop_assert!(range.is_disjoint(&range2));
prop_assert!(!range.is_touching(&range2));
prop_assert!(!range.is_overlapping(&range2));
prop_assert!(!range.is_starting_with(&range2));
prop_assert!(!range.is_ending_with(&range2));
prop_assert!(!range.is_equal(&range2));
if let Some(self_empty) = self_empty {
if self_empty {
prop_assert!(!range.is_containing(&range2));
prop_assert!(range.is_contained_by(&range2));
prop_assert!(range.is_empty());
prop_assert!(!range2.is_empty());
} else {
prop_assert!(range.is_containing(&range2));
prop_assert!(!range.is_contained_by(&range2));
prop_assert!(!range.is_empty());
prop_assert!(range2.is_empty());
}
} else {
prop_assert!(range.is_empty());
prop_assert!(range2.is_empty());
prop_assert!(range.is_containing(&range2));
prop_assert!(range.is_contained_by(&range2));
}
},
}
}
}
#[test]
fn proptest_regression_ef1f382ef046c89c98c6650bf4e5e089142b0384f653a2eedeb618c1b828d3bf() {
let range1 = GenericRange::from(34..189);
let range2 = GenericRange::from(0..=0);
assert_eq!(range1.arrangement(&range2), Arrangement::Disjoint { self_less: false });
assert!(!range1.is_overlapping(&range2));
}
#[test]
fn proptest_regression_6b871bef71a563b2b17b385dc62a2c6b911d8ecf35c3767035ed8fe5e4cca5bf() {
let range1 = GenericRange::from(191..191);
let range2 = GenericRange::from(0..191);
assert_eq!(
range1.arrangement(&range2),
Arrangement::Empty { self_empty: Some(true) }
);
assert!(!range1.is_touching(&range2));
}
#[test]
fn proptest_regression_88449f8d7ce537174697fa2d7549720bac21b91f8f9d5926c279a57ea5bbc9f8() {
let range1 = GenericRange::from(0..132);
let range2 = GenericRange::new_open_closed(131, 132);
assert_eq!(range1.arrangement(&range2), Arrangement::Disjoint { self_less: true });
assert!(!range1.is_overlapping(&range2))
}
#[test]
fn proptest_regression_cb8f7fdcf3afe98e147cdfeda5493d83c57ac71537d80836d5392974d3f1cde4() {
let range1 = GenericRange::new_open_closed(81, 82);
let range2 = GenericRange::new_open(0, 82);
assert_eq!(range1.arrangement(&range2), Arrangement::Disjoint { self_less: false });
assert!(!range1.is_overlapping(&range2));
}
#[test]
fn proptest_regression_be3d67f34187b919ce7a8552b8f05814011fb47291e523b32737dce1b6b4c934() {
let range1 = GenericRange::from(0..=0);
let range2 = GenericRange::from(0..0);
assert_eq!(
range1.arrangement(&range2),
Arrangement::Empty {
self_empty: Some(false)
}
);
assert!(!range1.is_starting_with(&range2));
}
}
#[cfg(all(test, feature = "noisy_float"))]
mod tests_continuous {
use core::cmp::Ordering;
use core::ops::Bound;
use noisy_float::types::N64;
use crate::GenericRange;
#[test]
fn ordering_start_start_in_ex() {
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&N64::new(0.1)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&N64::new(0.2)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Included(&N64::new(0.3)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_start_start_ex_in() {
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&N64::new(0.1)), Bound::Included(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&N64::new(0.2)), Bound::Included(&N64::new(0.2))),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_start(Bound::Excluded(&N64::new(0.3)), Bound::Included(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_end_end_in_ex() {
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&N64::new(0.1)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&N64::new(0.2)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Included(&N64::new(0.3)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_end_end_ex_in() {
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&N64::new(0.1)), Bound::Included(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&N64::new(0.2)), Bound::Included(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_end(Bound::Excluded(&N64::new(0.3)), Bound::Included(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_same_ex() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&N64::new(0.1)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&N64::new(0.2)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&N64::new(0.3)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_in_ex() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&N64::new(0.1)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&N64::new(0.2)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Included(&N64::new(0.3)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_start_end_ex_in() {
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&N64::new(0.1)), Bound::Included(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&N64::new(0.2)), Bound::Included(&N64::new(0.2))),
Ordering::Greater
);
assert_eq!(
GenericRange::cmp_start_end(Bound::Excluded(&N64::new(0.3)), Bound::Included(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_same_ex() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&N64::new(0.1)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&N64::new(0.2)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&N64::new(0.3)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_in_ex() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&N64::new(0.1)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&N64::new(0.2)), Bound::Excluded(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Included(&N64::new(0.3)), Bound::Excluded(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn ordering_end_start_ex_in() {
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&N64::new(0.1)), Bound::Included(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&N64::new(0.2)), Bound::Included(&N64::new(0.2))),
Ordering::Less
);
assert_eq!(
GenericRange::cmp_end_start(Bound::Excluded(&N64::new(0.3)), Bound::Included(&N64::new(0.2))),
Ordering::Greater
);
}
#[test]
fn equality() {
let zero = N64::new(0.);
let one = N64::new(1.);
let two = N64::new(2.);
let three = N64::new(3.);
let four = N64::new(4.);
let five = N64::new(5.);
assert_eq!(GenericRange::from(one..three), GenericRange::from(one..three));
assert_eq!(GenericRange::from(one..=three), GenericRange::from(one..=three));
assert_ne!(GenericRange::from(one..three), GenericRange::from(one..=two));
assert_ne!(GenericRange::new_open_closed(one, two), GenericRange::from(two..=three));
assert_ne!(GenericRange::new_open(zero, five), GenericRange::from(one..=four));
}
}