1use crate::ops::{AsProxy, PartialOrd};
2use crate::ops_compare::{
3 value_cmp_bool, value_cmp_bool_reverse, value_cmp_f64, value_cmp_f64_reverse, value_cmp_i64,
4 value_cmp_i64_reverse, value_cmp_u64, value_cmp_u64_reverse, value_partial_cmp,
5};
6use crate::ops_macros::{impl_compare_matrix, impl_value_scalar_compare_op};
7use rbs::Value;
8use std::cmp::{Ordering, PartialOrd as StdPartialOrd};
9
10#[inline]
11fn cmp_i128(value: i128, rhs: i128) -> Option<Ordering> {
12 Some(value.cmp(&rhs))
13}
14
15#[inline]
16fn cmp_f64(value: f64, rhs: f64) -> Option<Ordering> {
17 value.partial_cmp(&rhs)
18}
19
20#[inline]
21fn cmp_bool(value: bool, rhs: bool) -> Option<Ordering> {
22 Some(value.cmp(&rhs))
23}
24
25#[inline]
26fn cmp_str(value: &str, rhs: &str) -> Option<Ordering> {
27 Some(value.cmp(rhs))
28}
29
30impl PartialOrd<Value> for Value {
31 fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
32 value_partial_cmp(self, rhs)
33 }
34}
35
36impl PartialOrd<&Value> for Value {
37 fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
38 value_partial_cmp(self, rhs)
39 }
40}
41
42impl PartialOrd<&&Value> for Value {
43 fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
44 value_partial_cmp(self, rhs)
45 }
46}
47
48impl PartialOrd<Value> for &Value {
49 fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
50 value_partial_cmp(self, rhs)
51 }
52}
53
54impl PartialOrd<&Value> for &Value {
55 fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
56 value_partial_cmp(self, rhs)
57 }
58}
59
60impl PartialOrd<&&Value> for &Value {
61 fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
62 value_partial_cmp(self, rhs)
63 }
64}
65
66impl PartialOrd<Value> for &&Value {
67 fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
68 value_partial_cmp(self, rhs)
69 }
70}
71
72impl PartialOrd<&Value> for &&Value {
73 fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
74 value_partial_cmp(self, rhs)
75 }
76}
77
78impl PartialOrd<&&Value> for &&Value {
79 fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
80 value_partial_cmp(self, rhs)
81 }
82}
83
84impl_value_scalar_compare_op!(
85 PartialOrd,
86 op_partial_cmp,
87 value_cmp_u64,
88 value_cmp_u64_reverse,
89 [u8, u16, u32, u64],
90 Option<Ordering>
91);
92impl_value_scalar_compare_op!(
93 PartialOrd,
94 op_partial_cmp,
95 value_cmp_i64,
96 value_cmp_i64_reverse,
97 [i8, i16, i32, i64, isize, usize],
98 Option<Ordering>
99);
100impl_value_scalar_compare_op!(
101 PartialOrd,
102 op_partial_cmp,
103 value_cmp_f64,
104 value_cmp_f64_reverse,
105 [f32, f64],
106 Option<Ordering>
107);
108impl_value_scalar_compare_op!(
109 PartialOrd,
110 op_partial_cmp,
111 value_cmp_bool,
112 value_cmp_bool_reverse,
113 [bool],
114 Option<Ordering>
115);
116
117macro_rules! impl_same_type_cmp {
118 ($compare:ident [$($ty:ty)*]) => {
119 $(
120 impl PartialOrd<$ty> for $ty {
121 fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
122 $compare(*self as _, *rhs as _)
123 }
124 }
125
126 impl PartialOrd<&$ty> for $ty {
127 fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
128 $compare(*self as _, **rhs as _)
129 }
130 }
131
132 impl PartialOrd<$ty> for &$ty {
133 fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
134 $compare(**self as _, *rhs as _)
135 }
136 }
137
138 impl PartialOrd<&$ty> for &$ty {
139 fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
140 $compare(**self as _, **rhs as _)
141 }
142 }
143 )*
144 };
145}
146
147impl_same_type_cmp! {
148 cmp_bool [bool]
149}
150
151impl PartialOrd<&str> for &str {
152 fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
153 (*self).partial_cmp(*rhs)
154 }
155}
156
157impl PartialOrd<&str> for String {
158 fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
159 self.as_str().partial_cmp(*rhs)
160 }
161}
162
163impl PartialOrd<String> for String {
164 fn op_partial_cmp(&self, rhs: &String) -> Option<Ordering> {
165 self.as_str().partial_cmp(rhs.as_str())
166 }
167}
168
169impl PartialOrd<&String> for String {
170 fn op_partial_cmp(&self, rhs: &&String) -> Option<Ordering> {
171 self.as_str().partial_cmp(rhs.as_str())
172 }
173}
174
175impl PartialOrd<&&String> for String {
176 fn op_partial_cmp(&self, rhs: &&&String) -> Option<Ordering> {
177 self.as_str().partial_cmp(rhs.as_str())
178 }
179}
180
181impl PartialOrd<&str> for &String {
182 fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
183 self.as_str().partial_cmp(*rhs)
184 }
185}
186
187impl PartialOrd<&&str> for &String {
188 fn op_partial_cmp(&self, rhs: &&&str) -> Option<Ordering> {
189 self.as_str().partial_cmp(**rhs)
190 }
191}
192
193impl PartialOrd<&&&str> for &String {
194 fn op_partial_cmp(&self, rhs: &&&&str) -> Option<Ordering> {
195 self.as_str().partial_cmp(***rhs)
196 }
197}
198
199impl PartialOrd<String> for &String {
200 fn op_partial_cmp(&self, rhs: &String) -> Option<Ordering> {
201 self.as_str().partial_cmp(rhs.as_str())
202 }
203}
204
205impl PartialOrd<&String> for &String {
206 fn op_partial_cmp(&self, rhs: &&String) -> Option<Ordering> {
207 self.as_str().partial_cmp(rhs.as_str())
208 }
209}
210
211impl PartialOrd<&&String> for &String {
212 fn op_partial_cmp(&self, rhs: &&&String) -> Option<Ordering> {
213 self.as_str().partial_cmp(rhs.as_str())
214 }
215}
216
217impl PartialOrd<String> for &&String {
218 fn op_partial_cmp(&self, rhs: &String) -> Option<Ordering> {
219 self.as_str().partial_cmp(rhs.as_str())
220 }
221}
222
223impl PartialOrd<&String> for &&String {
224 fn op_partial_cmp(&self, rhs: &&String) -> Option<Ordering> {
225 self.as_str().partial_cmp(rhs.as_str())
226 }
227}
228
229impl PartialOrd<&&String> for &&String {
230 fn op_partial_cmp(&self, rhs: &&&String) -> Option<Ordering> {
231 self.as_str().partial_cmp(rhs.as_str())
232 }
233}
234
235impl PartialOrd<&str> for Value {
236 fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
237 cmp_str(self.string().as_str(), rhs)
238 }
239}
240
241impl PartialOrd<&&str> for Value {
242 fn op_partial_cmp(&self, rhs: &&&str) -> Option<Ordering> {
243 cmp_str(self.string().as_str(), rhs)
244 }
245}
246
247impl PartialOrd<&str> for &Value {
248 fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
249 cmp_str(self.string().as_str(), rhs)
250 }
251}
252
253impl PartialOrd<&&str> for &Value {
254 fn op_partial_cmp(&self, rhs: &&&str) -> Option<Ordering> {
255 cmp_str(self.string().as_str(), rhs)
256 }
257}
258
259impl PartialOrd<&str> for &&Value {
260 fn op_partial_cmp(&self, rhs: &&str) -> Option<Ordering> {
261 cmp_str(self.string().as_str(), rhs)
262 }
263}
264
265impl PartialOrd<&&str> for &&Value {
266 fn op_partial_cmp(&self, rhs: &&&str) -> Option<Ordering> {
267 cmp_str(self.string().as_str(), rhs)
268 }
269}
270
271impl PartialOrd<Value> for &str {
272 fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
273 cmp_str(self, rhs.string().as_str())
274 }
275}
276
277impl PartialOrd<&Value> for &str {
278 fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
279 cmp_str(self, rhs.string().as_str())
280 }
281}
282
283impl PartialOrd<&&Value> for &str {
284 fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
285 cmp_str(self, rhs.string().as_str())
286 }
287}
288
289impl PartialOrd<Value> for &&str {
290 fn op_partial_cmp(&self, rhs: &Value) -> Option<Ordering> {
291 cmp_str(self, rhs.string().as_str())
292 }
293}
294
295impl PartialOrd<&Value> for &&str {
296 fn op_partial_cmp(&self, rhs: &&Value) -> Option<Ordering> {
297 cmp_str(self, rhs.string().as_str())
298 }
299}
300
301impl PartialOrd<&&Value> for &&str {
302 fn op_partial_cmp(&self, rhs: &&&Value) -> Option<Ordering> {
303 cmp_str(self, rhs.string().as_str())
304 }
305}
306
307impl_compare_matrix!(
308 PartialOrd,
309 op_partial_cmp,
310 cmp_i128,
311 i128,
312 Option<Ordering>;
313 u8 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
314 u16 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
315 u32 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
316 u64 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
317 usize => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
318 i8 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
319 i16 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
320 i32 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
321 i64 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
322 isize => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize]
323);
324impl_compare_matrix!(
325 PartialOrd,
326 op_partial_cmp,
327 cmp_f64,
328 f64,
329 Option<Ordering>;
330 u8 => [f32, f64],
331 u16 => [f32, f64],
332 u32 => [f32, f64],
333 u64 => [f32, f64],
334 usize => [f32, f64],
335 i8 => [f32, f64],
336 i16 => [f32, f64],
337 i32 => [f32, f64],
338 i64 => [f32, f64],
339 isize => [f32, f64],
340);
341impl_compare_matrix!(
342 PartialOrd,
343 op_partial_cmp,
344 cmp_f64,
345 f64,
346 Option<Ordering>;
347 f32 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
348 f64 => [u8, u16, u32, u64, usize, i8, i16, i32, i64, isize],
349);
350impl_compare_matrix!(
351 PartialOrd,
352 op_partial_cmp,
353 cmp_f64,
354 f64,
355 Option<Ordering>;
356 f32 => [f32, f64],
357 f64 => [f32, f64]
358);
359
360#[cfg(test)]
361mod test {
362 use crate::ops::PartialOrd;
363 use rbs::Value;
364 use std::cmp::Ordering;
365
366 #[test]
367 fn test_cmp() {
368 assert_eq!(
369 Value::I32(2).op_partial_cmp(&Value::I32(1)),
370 Some(Ordering::Greater)
371 );
372 assert_eq!(
373 (&&Value::I32(2)).op_partial_cmp(&Value::I32(1)),
374 Some(Ordering::Greater)
375 );
376 assert_eq!(1isize.op_partial_cmp(&1u8), Some(Ordering::Equal));
377 assert_eq!(1.0f32.op_partial_cmp(&1i64), Some(Ordering::Equal));
378 assert_eq!(true.op_partial_cmp(&false), Some(Ordering::Greater));
379 }
380}