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