#[cfg(feature="serde")] use serde::Deserialize;
#[cfg(feature="serde")] use serde::Serialize;
use std::borrow::Borrow;
use std::default::Default;
use self::Bound::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature="serde", derive(Deserialize, Serialize))]
pub enum Bound<T> {
Include(T),
Exclude(T),
Infinite,
}
impl<T> Bound<T> {
#[inline]
pub fn is_finite(&self) -> bool {
!matches!(self, Infinite)
}
#[inline]
pub fn is_inclusive(&self) -> bool {
matches!(self, Include(_))
}
#[inline]
pub fn is_exclusive(&self) -> bool {
matches!(self, Exclude(_))
}
#[inline]
pub fn as_ref(&self) -> Option<&T> {
match self {
Include(bound) |
Exclude(bound) => Some(bound),
Infinite => None,
}
}
#[inline]
pub fn as_mut(&mut self) -> Option<&mut T> {
match self {
Include(bound) |
Exclude(bound) => Some(bound),
Infinite => None,
}
}
#[inline]
pub fn unwrap(self) -> T {
match self {
Include(x) |
Exclude(x) => x,
Infinite
=> panic!("called `Bound::unwrap()` on an `Infinite` value"),
}
}
#[inline]
pub fn unwrap_or(self, def: T) -> T {
match self {
Include(x) |
Exclude(x) => x,
Infinite => def,
}
}
#[inline]
pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
match self {
Include(x) |
Exclude(x) => x,
Infinite => f(),
}
}
#[inline]
pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U> {
match self {
Include(x) => Include(f(x)),
Exclude(x) => Exclude(f(x)),
Infinite => Infinite,
}
}
#[inline]
pub fn map_or<U, F>(self, def: U, f: F) -> U where F: FnOnce(T) -> U {
match self {
Include(x) |
Exclude(x) => f(x),
Infinite => def,
}
}
#[inline]
pub fn map_or_else<U, D, F>(self, def: D, f: F) -> U
where
D: FnOnce() -> U,
F: FnOnce(T) -> U
{
match self {
Include(x) |
Exclude(x) => f(x),
Infinite => def(),
}
}
#[inline]
pub fn transfer<B: Borrow<Self>, O>(from: B, to: O) -> Bound<O> {
match *from.borrow() {
Include(_) => Include(to),
Exclude(_) => Exclude(to),
Infinite => Infinite,
}
}
}
impl<T> Bound<T> where T: PartialOrd {
#[allow(clippy::unnested_or_patterns)]
pub(in crate) fn is_union_adjacent_to(&self, other: &Self) -> bool {
matches!((self, other),
(Include(p), Include(o)) |
(Include(p), Exclude(o)) |
(Exclude(p), Include(o)) if p == o )
}
}
impl<T> Bound<T> where T: PartialOrd + Clone {
#[must_use]
pub fn least_union(&self, other: &Self) -> Self {
match (self, other) {
(Include(p), Include(o))
=> if p < o {Include(p.clone())} else {Include(o.clone())},
(Include(p), Exclude(o))
=> if p <= o {Include(p.clone())} else {Exclude(o.clone())},
(Exclude(p), Include(o))
=> if p < o {Exclude(p.clone())} else {Include(o.clone())},
(Exclude(p), Exclude(o))
=> if p < o {Exclude(p.clone())} else {Exclude(o.clone())},
_ => Infinite,
}
}
#[must_use]
pub fn least_intersect(&self, other: &Self) -> Self {
match (self, other) {
(Include(p), Include(o))
=> if p < o {Include(p.clone())} else {Include(o.clone())},
(Include(p), Exclude(o))
=> if p < o {Include(p.clone())} else {Exclude(o.clone())},
(Exclude(p), Include(o))
=> if p <= o {Exclude(p.clone())} else {Include(o.clone())},
(Exclude(p), Exclude(o))
=> if p < o {Exclude(p.clone())} else {Exclude(o.clone())},
(Include(p), Infinite) => Include(p.clone()),
(Exclude(p), Infinite) => Exclude(p.clone()),
(Infinite, Include(o)) => Include(o.clone()),
(Infinite, Exclude(o)) => Exclude(o.clone()),
_ => Infinite,
}
}
#[must_use]
pub fn greatest_union(&self, other: &Self) -> Self {
match (self, other) {
(Include(p), Include(o))
=> if p > o {Include(p.clone())} else {Include(o.clone())},
(Include(p), Exclude(o))
=> if p >= o {Include(p.clone())} else {Exclude(o.clone())},
(Exclude(p), Include(o))
=> if p > o {Exclude(p.clone())} else {Include(o.clone())},
(Exclude(p), Exclude(o))
=> if p > o {Exclude(p.clone())} else {Exclude(o.clone())},
_ => Infinite,
}
}
#[must_use]
pub fn greatest_intersect(&self, other: &Self) -> Self {
match (self, other) {
(Include(p), Include(o))
=> if p > o {Include(p.clone())} else {Include(o.clone())},
(Include(p), Exclude(o))
=> if p > o {Include(p.clone())} else {Exclude(o.clone())},
(Exclude(p), Include(o))
=> if p >= o {Exclude(p.clone())} else {Include(o.clone())},
(Exclude(p), Exclude(o))
=> if p > o {Exclude(p.clone())} else {Exclude(o.clone())},
(Include(p), Infinite) => Include(p.clone()),
(Exclude(p), Infinite) => Exclude(p.clone()),
(Infinite, Include(o)) => Include(o.clone()),
(Infinite, Exclude(o)) => Exclude(o.clone()),
_ => Infinite,
}
}
}
impl<T> Default for Bound<T> where T: Default {
#[inline]
fn default() -> Self {
Include(Default::default())
}
}
impl<T> From<T> for Bound<T> {
#[inline]
fn from(t: T) -> Self {
Include(t)
}
}