1use crate::ops::PartialOrd;
2use crate::ops::{AsProxy, Value};
3use std::cmp::{Ordering, PartialOrd as P};
4
5#[inline]
6fn cmp_u64(value: u64, other: u64) -> Option<Ordering> {
7 Some(value.cmp(&other))
8}
9#[inline]
10fn cmp_i64(value: i64, other: i64) -> Option<Ordering> {
11 Some(value.cmp(&other))
12}
13#[inline]
14fn cmp_f64(value: f64, other: f64) -> Option<Ordering> {
15 value.partial_cmp(&other)
16}
17#[inline]
18fn cmp_bool(value: bool, other: bool) -> Option<Ordering> {
19 Some(value.cmp(&other))
20}
21fn eq_u64(value: &Value, other: u64) -> Option<Ordering> {
26 let value = value.u64();
27 if value == other {
28 Some(Ordering::Equal)
29 } else if value > other {
30 Some(Ordering::Greater)
31 } else {
32 Some(Ordering::Less)
33 }
34}
35
36fn eq_i64(value: &Value, other: i64) -> Option<Ordering> {
37 let value = value.i64();
38 if value == other {
39 Some(Ordering::Equal)
40 } else if value > other {
41 Some(Ordering::Greater)
42 } else {
43 Some(Ordering::Less)
44 }
45}
46
47fn eq_f64(value: &Value, other: f64) -> Option<Ordering> {
48 let value = value.f64();
49 if value == other {
50 Some(Ordering::Equal)
51 } else if value > other {
52 Some(Ordering::Greater)
53 } else {
54 Some(Ordering::Less)
55 }
56}
57
58fn eq_bool(value: &Value, other: bool) -> Option<Ordering> {
59 let value = value.bool();
60 if value == other {
61 Some(Ordering::Equal)
62 } else if value == true && other == false {
63 Some(Ordering::Greater)
64 } else {
65 Some(Ordering::Less)
66 }
67}
68
69impl PartialOrd<Value> for Value {
70 fn op_partial_cmp(&self, other: &Value) -> Option<Ordering> {
71 match self {
72 Value::Null => Some(Ordering::Equal),
73 Value::Boolean(b) => cmp_bool(*b, other.bool()),
74 Value::Int32(n) => cmp_f64(*n as f64, other.f64()),
75 Value::Int64(n) => cmp_f64(*n as f64, other.f64()),
76 Value::UInt32(n) => cmp_u64(*n as u64, other.u64()),
77 Value::UInt64(n) => cmp_u64(*n as u64, other.u64()),
78 Value::Double(n) => cmp_f64(*n, other.f64()),
79 Value::String(s) => Some(s.cmp(&other.string())),
80 Value::Array(_) => None,
81 Value::Document(_) => None,
82 _ => None,
83 }
84 }
85}
86
87impl PartialOrd<Value> for &Value {
88 fn op_partial_cmp(&self, other: &Value) -> Option<Ordering> {
89 match self {
90 Value::Null => Some(Ordering::Equal),
91 Value::Boolean(b) => cmp_bool(*b, other.bool()),
92 Value::Int32(n) => cmp_f64(*n as f64, other.f64()),
93 Value::Int64(n) => cmp_f64(*n as f64, other.f64()),
94 Value::UInt32(n) => cmp_u64(*n as u64, other.u64()),
95 Value::UInt64(n) => cmp_u64(*n as u64, other.u64()),
96 Value::Double(n) => cmp_f64(*n, other.f64()),
97 Value::String(s) => Some(s.cmp(&other.string())),
98 Value::Array(_) => None,
99 Value::Document(_) => None,
100 _ => None,
101 }
102 }
103}
104
105impl PartialOrd<&Value> for &Value {
106 fn op_partial_cmp(&self, other: &&Value) -> Option<Ordering> {
107 match self {
108 Value::Null => Some(Ordering::Equal),
109 Value::Boolean(b) => cmp_bool(*b, other.bool()),
110 Value::Int32(n) => cmp_f64(*n as f64, other.f64()),
111 Value::Int64(n) => cmp_f64(*n as f64, other.f64()),
112 Value::UInt32(n) => cmp_u64(*n as u64, other.u64()),
113 Value::UInt64(n) => cmp_u64(*n as u64, other.u64()),
114 Value::Double(n) => cmp_f64(*n, other.f64()),
115 Value::String(s) => Some(s.cmp(&other.string())),
116 Value::Array(_) => None,
117 Value::Document(_) => None,
118 _ => None,
119 }
120 }
121}
122
123impl PartialOrd<&&Value> for &Value {
124 fn op_partial_cmp(&self, other: &&&Value) -> Option<Ordering> {
125 match self {
126 Value::Null => Some(Ordering::Equal),
127 Value::Boolean(b) => cmp_bool(*b, other.bool()),
128 Value::Int32(n) => cmp_f64(*n as f64, other.f64()),
129 Value::Int64(n) => cmp_f64(*n as f64, other.f64()),
130 Value::UInt32(n) => cmp_u64(*n as u64, other.u64()),
131 Value::UInt64(n) => cmp_u64(*n as u64, other.u64()),
132 Value::Double(n) => cmp_f64(*n, other.f64()),
133 Value::String(s) => Some(s.cmp(&other.string())),
134 Value::Array(_) => None,
135 Value::Document(_) => None,
136 _ => None,
137 }
138 }
139}
140
141impl PartialOrd<&Value> for Value {
142 fn op_partial_cmp(&self, other: &&Value) -> Option<Ordering> {
143 match self {
144 Value::Null => Some(Ordering::Equal),
145 Value::Boolean(b) => cmp_bool(*b, other.bool()),
146 Value::Int32(n) => cmp_f64(*n as f64, other.f64()),
147 Value::Int64(n) => cmp_f64(*n as f64, other.f64()),
148 Value::UInt32(n) => cmp_u64(*n as u64, other.u64()),
149 Value::UInt64(n) => cmp_u64(*n as u64, other.u64()),
150 Value::Double(n) => cmp_f64(*n, other.f64()),
151 Value::String(s) => Some(s.cmp(&other.string())),
152 Value::Array(_) => None,
153 Value::Document(_) => None,
154 _ => None,
155 }
156 }
157}
158
159impl PartialOrd<&&Value> for Value {
160 fn op_partial_cmp(&self, other: &&&Value) -> Option<Ordering> {
161 match self {
162 Value::Null => Some(Ordering::Equal),
163 Value::Boolean(b) => cmp_bool(*b, other.bool()),
164 Value::Int32(n) => cmp_f64(*n as f64, other.f64()),
165 Value::Int64(n) => cmp_f64(*n as f64, other.f64()),
166 Value::UInt32(n) => cmp_u64(*n as u64, other.u64()),
167 Value::UInt64(n) => cmp_u64(*n as u64, other.u64()),
168 Value::Double(n) => cmp_f64(*n, other.f64()),
169 Value::String(s) => Some(s.cmp(&other.string())),
170 Value::Array(_) => None,
171 Value::Document(_) => None,
172 _ => None,
173 }
174 }
175}
176
177macro_rules! impl_numeric_cmp {
178 ($($eq:ident [$($ty:ty)*])*) => {
179 $($(
180 impl PartialOrd<$ty> for Value {
181 fn op_partial_cmp(&self, other: &$ty) -> Option<Ordering> {
182 $eq(self, *other as _)
183 }
184 }
185
186 impl PartialOrd<Value> for $ty {
187 fn op_partial_cmp(&self, other: &Value) -> Option<Ordering> {
188 $eq(other, *self as _)
189 }
190 }
191
192 impl PartialOrd<&Value> for $ty {
193 fn op_partial_cmp(&self, other: &&Value) -> Option<Ordering> {
194 $eq(*other, *self as _)
195 }
196 }
197
198 impl PartialOrd<&&Value> for $ty {
199 fn op_partial_cmp(&self, other: &&&Value) -> Option<Ordering> {
200 $eq(**other, *self as _)
201 }
202 }
203
204 impl<'a> PartialOrd<$ty> for &'a Value {
205 fn op_partial_cmp(&self, other: &$ty) -> Option<Ordering> {
206 $eq(*self, *other as _)
207 }
208 }
209 )*)*
210 }
211}
212
213impl_numeric_cmp! {
214 eq_u64[u8 u16 u32 u64]
215 eq_i64[i8 i16 i32 i64 isize]
216 eq_f64[f32 f64]
217 eq_bool[bool]
218}
219
220macro_rules! cmp_self {
221 ($eq:ident[$($ty:ty)*]) => {
222 $(
223impl PartialOrd<$ty> for $ty{
224 fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
225 $eq(*self as _, *rhs as _)
226 }
227 }
228impl PartialOrd<&$ty> for $ty{
229 fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
230 $eq(*self as _, **rhs as _)
231 }
232 }
233impl PartialOrd<$ty> for &$ty{
234 fn op_partial_cmp(&self, rhs: &$ty) -> Option<Ordering> {
235 $eq(**self as _, *rhs as _)
236 }
237 }
238impl PartialOrd<&$ty> for &$ty{
239 fn op_partial_cmp(&self, rhs: &&$ty) -> Option<Ordering> {
240 $eq(**self as _, **rhs as _)
241 }
242 }
243 )*
244 };
245}
246
247cmp_self!(cmp_u64[u8 u16 u32 u64]);
248cmp_self!(cmp_i64[i8 i16 i32 i64 isize]);
249cmp_self!(cmp_f64[f32 f64]);
250
251impl PartialOrd<&str> for &str {
252 fn op_partial_cmp(&self, other: &&str) -> Option<Ordering> {
253 self.partial_cmp(other)
254 }
255}
256
257impl PartialOrd<String> for String {
264 fn op_partial_cmp(&self, other: &String) -> Option<Ordering> {
265 self.as_str().partial_cmp(other.as_str())
266 }
267}
268
269impl PartialOrd<String> for &String {
276 fn op_partial_cmp(&self, other: &String) -> Option<Ordering> {
277 self.as_str().partial_cmp(other.as_str())
278 }
279}