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