use crate::{
interval::{Interval, IntervalFrom, IntervalFull, IntervalTo},
NonEmpty,
};
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub enum Bound<T> {
Bounded(T),
Unbounded,
}
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
pub struct Bounds<T> {
pub start: Bound<T>,
pub end: Bound<T>,
}
pub trait IntervalBounds<T> {
fn start_bound(&self) -> Bound<T>;
fn end_bound(&self) -> Bound<T>;
fn bounds(&self) -> Bounds<T> {
Bounds {
start: self.start_bound(),
end: self.end_bound(),
}
}
}
impl<I, T> IntervalBounds<T> for NonEmpty<I>
where
I: IntervalBounds<T>,
{
fn start_bound(&self) -> Bound<T> {
self.0.start_bound()
}
fn end_bound(&self) -> Bound<T> {
self.0.end_bound()
}
}
impl<T> IntervalBounds<T> for Interval<T>
where
T: Copy,
{
fn start_bound(&self) -> Bound<T> {
Bound::Bounded(self.start)
}
fn end_bound(&self) -> Bound<T> {
Bound::Bounded(self.end)
}
}
impl<T> IntervalBounds<T> for IntervalFrom<T>
where
T: Copy,
{
fn start_bound(&self) -> Bound<T> {
Bound::Bounded(self.start)
}
fn end_bound(&self) -> Bound<T> {
Bound::Unbounded
}
}
impl<T> IntervalBounds<T> for IntervalTo<T>
where
T: Copy,
{
fn start_bound(&self) -> Bound<T> {
Bound::Unbounded
}
fn end_bound(&self) -> Bound<T> {
Bound::Bounded(self.end)
}
}
impl<T> IntervalBounds<T> for IntervalFull {
fn start_bound(&self) -> Bound<T> {
Bound::Unbounded
}
fn end_bound(&self) -> Bound<T> {
Bound::Unbounded
}
}