try_traits/
cmp.rs

1//! Try traits for [`core::cmp`].
2
3use core::cmp::{Ord, PartialOrd, Ordering};
4
5/// The try trait for [`PartialEq`].
6pub trait TryPartialEq<Rhs: ?Sized = Self> {
7	/// The type returned in the event of an error.
8	type Error;
9
10	/// The fallible equivalent of [`PartialEq::eq`].
11	fn try_eq(&self, other: &Rhs) -> Result<bool, Self::Error>;
12
13	/// The fallible equivalent of [`PartialEq::ne`].
14	#[inline]
15	fn try_ne(&self, other: &Rhs) -> Result<bool, Self::Error> {
16		Ok(!self.try_eq(other)?)
17	}
18}
19
20/// The try trait for [`Eq`].
21///
22/// That is, if the `try_eq` method returns `Ok`, then the requirements of `Eq` hold.
23pub trait TryEq : TryPartialEq<Self> {}
24
25/// The try trait for [`PartialOrd`].
26pub trait TryPartialOrd<Rhs: ?Sized = Self> : TryPartialEq<Rhs> {
27	/// The fallible equivalent of [`PartialOrd::partial_cmp`].
28	fn try_partial_cmp(&self, other: &Rhs) -> Result<Option<Ordering>, Self::Error>;
29
30	/// The fallible equivalent of [`PartialOrd::lt`].
31	fn try_lt(&self, other: &Rhs) -> Result<bool, Self::Error> {
32		Ok(matches!(self.try_partial_cmp(other)?, Some(Ordering::Less)))
33	}
34
35	/// The fallible equivalent of [`PartialOrd::le`].
36	fn try_le(&self, other: &Rhs) -> Result<bool, Self::Error> {
37		Ok(!matches!(self.try_partial_cmp(other)?, Some(Ordering::Greater)))
38	}
39
40	/// The fallible equivalent of [`PartialOrd::gt`].
41	fn try_gt(&self, other: &Rhs) -> Result<bool, Self::Error> {
42		Ok(matches!(self.try_partial_cmp(other)?, Some(Ordering::Greater)))
43	}
44
45	/// The fallible equivalent of [`PartialOrd::gt`].
46	fn try_ge(&self, other: &Rhs) -> Result<bool, Self::Error> {
47		Ok(!matches!(self.try_partial_cmp(other)?, Some(Ordering::Less)))
48	}
49}
50
51/// The try trait for [`Ord`].
52pub trait TryOrd : TryEq + TryPartialOrd<Self> {
53	/// The fallible equivalent of [`Ord::cmp`].
54	fn try_cmp(&self, other: &Self) -> Result<Ordering, Self::Error>;
55
56	/// The fallible equivalent of [`Ord::max`].
57	fn try_max(self, other: Self) -> Result<Self, Self::Error>
58	where
59		Self: Sized
60	{
61		match self.try_cmp(&other)? {
62			Ordering::Less | Ordering::Equal => Ok(other),
63			Ordering::Greater => Ok(self)
64		}
65	}
66
67	/// The fallible equivalent of [`Ord::min`].
68	fn try_min(self, other: Self) -> Result<Self, Self::Error>
69	where
70		Self: Sized
71	{
72		match self.try_cmp(&other)? {
73			Ordering::Less | Ordering::Equal => Ok(self),
74			Ordering::Greater => Ok(other)
75		}
76	}
77
78	/// The fallible equivalent of [`Ord::clamp`].
79	///
80	/// # Panics
81	///
82	/// Panics if `min > max`
83	fn try_clamp(self, min: Self, max: Self) -> Result<Self, Self::Error>
84	where
85		Self: Sized
86	{
87		if self.try_lt(&min)? {
88			Ok(min)
89		} else if self.try_gt(&max)? {
90			Ok(max)
91		} else {
92			Ok(self)
93		}
94	}
95}
96
97impl<T: PartialEq<Rhs>, Rhs: ?Sized> TryPartialEq<Rhs> for T {
98	type Error = crate::Infallible;
99
100	#[inline]
101	fn try_eq(&self, other: &Rhs) -> Result<bool, Self::Error> {
102		Ok(self == other)
103	}
104
105	#[inline]
106	fn try_ne(&self, other: &Rhs) -> Result<bool, Self::Error> {
107		Ok(self != other)
108	}
109}
110
111impl<T: Eq> TryEq for T {}
112
113impl<T: PartialOrd<Rhs>, Rhs: ?Sized> TryPartialOrd<Rhs> for T {
114	#[inline]
115	fn try_partial_cmp(&self, other: &Rhs) -> Result<Option<Ordering>, Self::Error> {
116		Ok(self.partial_cmp(other))
117	}
118
119	#[inline]
120	fn try_lt(&self, other: &Rhs) -> Result<bool, Self::Error> {
121		Ok(self < other)
122	}
123
124	#[inline]
125	fn try_le(&self, other: &Rhs) -> Result<bool, Self::Error> {
126		Ok(self <= other)
127	}
128
129	#[inline]
130	fn try_gt(&self, other: &Rhs) -> Result<bool, Self::Error> {
131		Ok(self > other)
132	}
133
134	#[inline]
135	fn try_ge(&self, other: &Rhs) -> Result<bool, Self::Error> {
136		Ok(self >= other)
137	}
138}
139
140impl<T: Ord> TryOrd for T {
141	#[inline]
142	fn try_cmp(&self, other: &Self) -> Result<Ordering, Self::Error> {
143		Ok(self.cmp(other))
144	}
145
146	#[inline]
147	fn try_max(self, other: Self) -> Result<Self, Self::Error>
148	where
149		Self: Sized
150	{
151		Ok(self.max(other))
152	}
153
154	#[inline]
155	fn try_min(self, other: Self) -> Result<Self, Self::Error>
156	where
157		Self: Sized
158	{
159		Ok(self.min(other))
160	}
161
162	fn try_clamp(self, min: Self, max: Self) -> Result<Self, Self::Error>
163	where
164		Self: Sized
165	{
166		#[cfg(feature = "nightly_clamp")]
167		{
168			Ok(self.clamp(min, max))
169		}
170		#[cfg(not(feature = "nightly_clamp"))]
171		{
172			Ok(if self < min {
173				min
174			} else if self > max {
175				max
176			} else {
177				self
178			})
179		}
180	}
181}