use core::cmp::{Ord, PartialOrd, Ordering};
pub trait TryPartialEq<Rhs: ?Sized = Self> {
type Error;
fn try_eq(&self, other: &Rhs) -> Result<bool, Self::Error>;
#[inline]
fn try_ne(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(!self.try_eq(other)?)
}
}
pub trait TryEq : TryPartialEq<Self> {}
pub trait TryPartialOrd<Rhs: ?Sized = Self> : TryPartialEq<Rhs> {
fn try_partial_cmp(&self, other: &Rhs) -> Result<Option<Ordering>, Self::Error>;
fn try_lt(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(matches!(self.try_partial_cmp(other)?, Some(Ordering::Less)))
}
fn try_le(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(!matches!(self.try_partial_cmp(other)?, Some(Ordering::Greater)))
}
fn try_gt(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(matches!(self.try_partial_cmp(other)?, Some(Ordering::Greater)))
}
fn try_ge(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(!matches!(self.try_partial_cmp(other)?, Some(Ordering::Less)))
}
}
pub trait TryOrd : TryEq + TryPartialOrd<Self> {
fn try_cmp(&self, other: &Self) -> Result<Ordering, Self::Error>;
fn try_max(self, other: Self) -> Result<Self, Self::Error>
where
Self: Sized
{
match self.try_cmp(&other)? {
Ordering::Less | Ordering::Equal => Ok(other),
Ordering::Greater => Ok(self)
}
}
fn try_min(self, other: Self) -> Result<Self, Self::Error>
where
Self: Sized
{
match self.try_cmp(&other)? {
Ordering::Less | Ordering::Equal => Ok(self),
Ordering::Greater => Ok(other)
}
}
fn try_clamp(self, min: Self, max: Self) -> Result<Self, Self::Error>
where
Self: Sized
{
if self.try_lt(&min)? {
Ok(min)
} else if self.try_gt(&max)? {
Ok(max)
} else {
Ok(self)
}
}
}
impl<T: PartialEq<Rhs>, Rhs: ?Sized> TryPartialEq<Rhs> for T {
type Error = crate::Infallible;
#[inline]
fn try_eq(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(self == other)
}
#[inline]
fn try_ne(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(self != other)
}
}
impl<T: Eq> TryEq for T {}
impl<T: PartialOrd<Rhs>, Rhs: ?Sized> TryPartialOrd<Rhs> for T {
#[inline]
fn try_partial_cmp(&self, other: &Rhs) -> Result<Option<Ordering>, Self::Error> {
Ok(self.partial_cmp(other))
}
#[inline]
fn try_lt(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(self < other)
}
#[inline]
fn try_le(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(self <= other)
}
#[inline]
fn try_gt(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(self > other)
}
#[inline]
fn try_ge(&self, other: &Rhs) -> Result<bool, Self::Error> {
Ok(self >= other)
}
}
impl<T: Ord> TryOrd for T {
#[inline]
fn try_cmp(&self, other: &Self) -> Result<Ordering, Self::Error> {
Ok(self.cmp(other))
}
#[inline]
fn try_max(self, other: Self) -> Result<Self, Self::Error>
where
Self: Sized
{
Ok(self.max(other))
}
#[inline]
fn try_min(self, other: Self) -> Result<Self, Self::Error>
where
Self: Sized
{
Ok(self.min(other))
}
fn try_clamp(self, min: Self, max: Self) -> Result<Self, Self::Error>
where
Self: Sized
{
#[cfg(feature = "nightly_clamp")]
{
Ok(self.clamp(min, max))
}
#[cfg(not(feature = "nightly_clamp"))]
{
Ok(if self < min {
min
} else if self > max {
max
} else {
self
})
}
}
}