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