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