pub trait EndpointToggle {
fn toggle(self) -> Self;
}
pub trait EndpointMap {
type EndpointValue;
fn map_endpoint(self, f: impl Fn(Self::EndpointValue) -> Self::EndpointValue) -> Self;
}
pub trait EndpointMapInto<U> {
type EndpointValue;
type Output;
fn map_endpoint_into(self, f: impl Fn(Self::EndpointValue) -> U) -> Self::Output;
}
#[derive(Debug, Clone, PartialEq)]
pub struct Interval<E, V> {
left_endpoint: LeftT<E>,
right_endpoint: RightT<E>,
value: V,
}
#[derive(Debug, Clone, PartialEq)]
pub enum LeftT<T> {
Left(T),
}
use LeftT::*;
#[derive(Debug, Clone, PartialEq)]
pub enum RightT<T> {
Right(T),
}
use RightT::*;
impl<T> RightT<T> {
pub fn endpoint(&self) -> &T {
let Right(v) = self;
v
}
}
impl<T> LeftT<T> {
pub fn endpoint(&self) -> &T {
let Left(v) = self;
v
}
}
impl<E, V> Interval<E, V> {
pub fn left_endpoint(&self) -> &LeftT<E> {
&self.left_endpoint
}
pub fn right_endpoint(&self) -> &RightT<E> {
&self.right_endpoint
}
pub fn value_ref(&self) -> &V {
&self.value
}
pub fn left(&self) -> LeftT<E>
where
E: Clone,
{
self.left_endpoint.clone()
}
pub fn right(&self) -> RightT<E>
where
E: Clone,
{
self.right_endpoint.clone()
}
pub fn value(&self) -> V
where
V: Copy,
{
self.value
}
pub fn ref_val(&self) -> Interval<E, &V>
where
E: Clone,
{
Interval::new_lr(
self.left_endpoint.clone(),
self.right_endpoint.clone(),
&self.value,
)
}
pub fn new(left_endpoint: E, right_endpoint: E, value: V) -> Self {
Interval {
left_endpoint: Left(left_endpoint),
right_endpoint: Right(right_endpoint),
value,
}
}
pub fn new_lr(left: LeftT<E>, right: RightT<E>, value: V) -> Self {
Interval {
left_endpoint: left,
right_endpoint: right,
value,
}
}
}
impl<E> LeftT<E> {
pub fn into_right(self) -> RightT<E>
where
E: EndpointToggle,
{
let Left(x) = self;
Right(x.toggle())
}
pub fn value(self) -> E {
let Left(x) = self;
x
}
}
impl<E> RightT<E> {
pub fn into_left(self) -> LeftT<E>
where
E: EndpointToggle,
{
let Right(x) = self;
Left(x.toggle())
}
pub fn value(self) -> E {
let Right(x) = self;
x
}
}
impl<E> EndpointMap for LeftT<E>
where
E: EndpointMap,
{
type EndpointValue = E::EndpointValue;
fn map_endpoint(self, f: impl Fn(E::EndpointValue) -> E::EndpointValue) -> Self {
Left(self.value().map_endpoint(f))
}
}
impl<E> EndpointMap for RightT<E>
where
E: EndpointMap,
{
type EndpointValue = E::EndpointValue;
fn map_endpoint(self, f: impl Fn(E::EndpointValue) -> E::EndpointValue) -> Self {
Right(self.value().map_endpoint(f))
}
}
impl<E, U> EndpointMapInto<U> for LeftT<E>
where
E: EndpointMapInto<U>,
{
type EndpointValue = E::EndpointValue;
type Output = LeftT<E::Output>;
fn map_endpoint_into(self, f: impl Fn(E::EndpointValue) -> U) -> LeftT<E::Output> {
Left(self.value().map_endpoint_into(f))
}
}
impl<E, U> EndpointMapInto<U> for RightT<E>
where
E: EndpointMapInto<U>,
{
type EndpointValue = E::EndpointValue;
type Output = RightT<E::Output>;
fn map_endpoint_into(self, f: impl Fn(E::EndpointValue) -> U) -> RightT<E::Output> {
Right(self.value().map_endpoint_into(f))
}
}