use crate::PosStyle;
use crate::shorthands::aliases::*;
use core::mem;
use core::ops::Bound;
#[inline]
pub(crate) fn bound<T>(bound: Bound<T>) -> BoundWrapper<T> {
BoundWrapper::new(bound)
}
#[inline]
pub(crate) fn bound_ref<T>(bound: &Bound<T>) -> &BoundWrapper<T> {
unsafe { mem::transmute(bound) }
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub(crate) struct BoundWrapper<T>(pub Bound<T>);
impl<T> BoundWrapper<T> {
pub fn new(base: Bound<T>) -> Self {
Self(base)
}
pub fn pos(self) -> Option<T> {
match self.0 {
In(x) => Some(x),
Ex(x) => Some(x),
Ub => None,
}
}
pub fn kind(self) -> Option<bool> {
match self.0 {
In(_) => Some(true),
Ex(_) => Some(false),
Ub => None,
}
}
pub fn toggle_included(self) -> Bound<T> {
match self.0 {
Ub => Ub,
In(x) => Ex(x),
Ex(x) => In(x),
}
}
pub fn with_included(self, value: bool) -> Bound<T> {
match self.0 {
Ub => Ub,
In(x) | Ex(x) => (if value { In } else { Ex })(x),
}
}
pub fn with_pos(self, value: T) -> Bound<T> {
match self.0 {
Ub => Ub,
In(_) => In(value),
Ex(_) => Ex(value),
}
}
pub fn adjoins(&self, other: &Bound<T>) -> bool
where
T: PartialEq,
{
matches!((&self.0, other), (In(x), In(y)) if x == y)
}
pub fn touches(&self, other: &Bound<T>) -> bool
where
T: PartialEq,
{
matches!((&self.0, other), (In(x), Ex(y)) | (Ex(x), In(y)) if x == y)
}
pub fn meets(&self, other: &Bound<T>, ps: PosStyle) -> bool
where
T: PartialEq,
{
match ps {
PosStyle::Real => self.adjoins(other),
PosStyle::Step => self.touches(other),
}
}
pub fn map<F, U>(self, f: F) -> Bound<U>
where
F: FnOnce(T) -> U,
{
self.0.map(f)
}
pub fn try_map<F, U>(self, f: F) -> Option<Bound<U>>
where
F: FnOnce(T) -> Option<U>,
{
match self.0 {
In(x) => Some(In(f(x)?)),
Ex(x) => Some(Ex(f(x)?)),
Ub => Some(Ub),
}
}
}