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#[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
157macro_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
221use 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}