sonic_rs/value/
partial_eq.rs

1use faststr::FastStr;
2
3use crate::value::{
4    node::{Value, ValueRefInner},
5    value_trait::{JsonContainerTrait, JsonValueTrait},
6};
7impl Eq for Value {}
8
9impl PartialEq for Value {
10    #[inline]
11    fn eq(&self, other: &Self) -> bool {
12        if self.get_type() != other.get_type() {
13            return false;
14        }
15        match self.as_ref2() {
16            ValueRefInner::Null => other.is_null(),
17            ValueRefInner::Bool(a) => other.as_bool() == Some(a),
18            ValueRefInner::Number(_) | ValueRefInner::RawNum(_) => {
19                other.as_number() == self.as_number()
20            }
21            ValueRefInner::Str(a) => other.as_str() == Some(a),
22            ValueRefInner::Array(_) | ValueRefInner::EmptyArray => {
23                other.as_value_slice() == self.as_value_slice()
24            }
25            ValueRefInner::Object(_)
26            | ValueRefInner::EmptyObject
27            | ValueRefInner::ObjectOwned(_) => other.as_object() == self.as_object(),
28        }
29    }
30}
31
32macro_rules! impl_str_eq {
33    ($($eq:ident [$($ty:ty)*])*) => {
34        $($(
35            impl PartialEq<$ty> for Value {
36                #[inline]
37                fn eq(&self, other: &$ty) -> bool {
38                    let s: &str = other.as_ref();
39                    $eq(self, s)
40                }
41            }
42
43            impl PartialEq<Value> for $ty {
44                #[inline]
45                fn eq(&self, other: &Value) -> bool {
46                    let s: &str = self.as_ref();
47                    $eq(other, s)
48                }
49            }
50
51            impl PartialEq<$ty> for &Value {
52                #[inline]
53                fn eq(&self, other: &$ty) -> bool {
54                    let s: &str = other.as_ref();
55                    $eq(*self, s)
56                }
57            }
58
59            impl PartialEq<$ty> for &mut Value {
60                #[inline]
61                fn eq(&self, other: &$ty) -> bool {
62                    let s: &str = other.as_ref();
63                    $eq(*self, s)
64                }
65            }
66        )*)*
67    }
68}
69
70impl_str_eq! {
71    eq_str[str String FastStr]
72}
73
74impl PartialEq<&str> for Value {
75    #[inline]
76    fn eq(&self, other: &&str) -> bool {
77        eq_str(self, other)
78    }
79}
80
81impl PartialEq<Value> for &str {
82    #[inline]
83    fn eq(&self, other: &Value) -> bool {
84        eq_str(other, self)
85    }
86}
87
88///////////////////////////////////////////////////////////////////
89// Copied from serde_json
90
91#[inline]
92fn eq_i64(value: &Value, other: i64) -> bool {
93    value.as_i64() == Some(other)
94}
95
96#[inline]
97fn eq_u64(value: &Value, other: u64) -> bool {
98    value.as_u64() == Some(other)
99}
100
101#[inline]
102fn eq_f64(value: &Value, other: f64) -> bool {
103    value.as_f64() == Some(other)
104}
105
106#[inline]
107fn eq_bool(value: &Value, other: bool) -> bool {
108    value.as_bool() == Some(other)
109}
110
111#[inline]
112fn eq_str(value: &Value, other: &str) -> bool {
113    value.as_str() == Some(other)
114}
115
116macro_rules! impl_numeric_eq {
117    ($($eq:ident [$($ty:ty)*])*) => {
118        $($(
119            impl PartialEq<$ty> for Value {
120                #[inline]
121                fn eq(&self, other: &$ty) -> bool {
122                    $eq(self, *other as _)
123                }
124            }
125
126            impl PartialEq<Value> for $ty {
127                #[inline]
128                fn eq(&self, other: &Value) -> bool {
129                    $eq(other, *self as _)
130                }
131            }
132
133            impl PartialEq<$ty> for &Value {
134                #[inline]
135                fn eq(&self, other: &$ty) -> bool {
136                    $eq(*self, *other as _)
137                }
138            }
139
140            impl PartialEq<$ty> for &mut Value {
141                #[inline]
142                fn eq(&self, other: &$ty) -> bool {
143                    $eq(*self, *other as _)
144                }
145            }
146        )*)*
147    }
148}
149
150impl_numeric_eq! {
151    eq_i64[i8 i16 i32 i64 isize]
152    eq_u64[u8 u16 u32 u64 usize]
153    eq_f64[f32 f64]
154    eq_bool[bool]
155}
156
157//////////////////////////////////////////////////////////////////////////////
158
159macro_rules! impl_slice_eq {
160    ([$($vars:tt)*], $rhs:ty $(where $ty:ty: $bound:ident)?) => {
161        impl<U, $($vars)*> PartialEq<$rhs> for Array
162        where
163            Value: PartialEq<U>,
164            $($ty: $bound)?
165        {
166            #[inline]
167            fn eq(&self, other: &$rhs) -> bool {
168                let len = self.len();
169                if len != other.len() {
170                    return false;
171                }
172                let slf = self.as_ref();
173                let other: &[U] = other.as_ref();
174                slf.iter().zip(other).all(|(a, b)| *a == *b )
175            }
176        }
177
178        impl<U, $($vars)*> PartialEq<$rhs> for Value
179        where
180            Value: PartialEq<U>,
181            $($ty: $bound)?
182        {
183            #[inline]
184            fn eq(&self, other: &$rhs) -> bool {
185                self.as_array().map(|arr| arr == other).unwrap_or(false)
186            }
187        }
188
189
190        impl<U, $($vars)*> PartialEq<Array> for $rhs
191        where
192            Value: PartialEq<U>,
193            $($ty: $bound)?
194        {
195            #[inline]
196            fn eq(&self, other: &Array) -> bool {
197                other == self
198            }
199        }
200
201        impl<U, $($vars)*> PartialEq<Value> for $rhs
202        where
203            Value: PartialEq<U>,
204            $($ty: $bound)?
205        {
206            #[inline]
207            fn eq(&self, other: &Value) -> bool {
208                other == self
209            }
210        }
211    }
212}
213
214impl_slice_eq!([], &[U]);
215impl_slice_eq!([], &mut [U]);
216impl_slice_eq!([], [U]);
217impl_slice_eq!([const N: usize], &[U; N]);
218impl_slice_eq!([const N: usize], [U; N]);
219impl_slice_eq!([], Vec<U>);
220
221//////////////////////////////////////////////////////////////////////////////
222
223use super::{array::Array, object::Object};
224
225macro_rules! impl_container_eq {
226    ($($ty:ty)*) => {
227        $(
228            impl PartialEq<$ty> for Value {
229                #[inline]
230                fn eq(&self, other: &$ty) -> bool {
231                    self == &other.0
232                }
233            }
234
235            impl PartialEq<Value> for $ty {
236                #[inline]
237                fn eq(&self, other: &Value) -> bool {
238                    other == &self.0
239                }
240            }
241
242            impl  PartialEq<$ty> for &Value {
243                #[inline]
244                fn eq(&self, other: &$ty) -> bool {
245                    *self == &other.0
246                }
247            }
248
249            impl  PartialEq<$ty> for &mut Value {
250                #[inline]
251                fn eq(&self, other: &$ty) -> bool {
252                    *self == &other.0
253                }
254            }
255
256            impl PartialEq<Value> for &$ty {
257                #[inline]
258                fn eq(&self, other: &Value) -> bool {
259                    other == &self.0
260                }
261            }
262
263            impl PartialEq<Value> for &mut $ty {
264                #[inline]
265                fn eq(&self, other: &Value) -> bool {
266                    other == &self.0
267                }
268            }
269
270        )*
271    }
272}
273
274impl_container_eq!(Array Object);
275
276#[cfg(test)]
277mod test {
278    use faststr::FastStr;
279
280    #[test]
281    fn test_slice_eq() {
282        assert_eq!(json!([1, 2, 3]), &[1, 2, 3]);
283        assert_eq!(array![1, 2, 3], &[1, 2, 3]);
284        assert_eq!(json!([1, 2, 3]), array![1, 2, 3].as_slice());
285
286        assert_eq!(json!([1, 2, 3]), vec![1, 2, 3]);
287        assert_eq!(vec![1, 2, 3], array![1, 2, 3]);
288        assert_eq!(array![1, 2, 3], &[1, 2, 3][..]);
289        assert_eq!(json!([1, 2, 3]), array![1, 2, 3].as_slice());
290    }
291
292    #[test]
293    fn test_str_eq() {
294        assert_eq!(json!("123"), FastStr::new("123"));
295        assert_eq!(json!("123"), "123");
296    }
297
298    #[test]
299    fn test_container_eq() {
300        assert_eq!(json!([1, 2, 3]), array![1, 2, 3]);
301        assert_eq!(array![1, 2, 3], json!([1, 2, 3]));
302        assert_eq!(json!({"a": 1, "b": 2}), json!({"b": 2, "a": 1}));
303        assert_eq!(json!({"a": 1, "b": 2}), object! {"a": 1, "b": 2});
304        assert_eq!(object! {"a": 1, "b": 2}, json!({"a": 1, "b": 2}));
305    }
306}