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