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
88macro_rules! impl_eq_fn {
92 ($($name:ident($ty:ty) => $accessor:ident;)*) => {
93 $(
94 #[inline]
95 fn $name(value: &Value, other: $ty) -> bool {
96 value.$accessor() == Some(other)
97 }
98 )*
99 };
100}
101
102impl_eq_fn! {
103 eq_i64(i64) => as_i64;
104 eq_u64(u64) => as_u64;
105 eq_f64(f64) => as_f64;
106 eq_bool(bool) => as_bool;
107}
108
109#[inline]
110fn eq_str(value: &Value, other: &str) -> bool {
111 value.as_str() == Some(other)
112}
113
114macro_rules! impl_numeric_eq {
115 ($($eq:ident [$($ty:ty)*])*) => {
116 $($(
117 impl PartialEq<$ty> for Value {
118 #[inline]
119 fn eq(&self, other: &$ty) -> bool {
120 $eq(self, *other as _)
121 }
122 }
123
124 impl PartialEq<Value> for $ty {
125 #[inline]
126 fn eq(&self, other: &Value) -> bool {
127 $eq(other, *self as _)
128 }
129 }
130
131 impl PartialEq<$ty> for &Value {
132 #[inline]
133 fn eq(&self, other: &$ty) -> bool {
134 $eq(*self, *other as _)
135 }
136 }
137
138 impl PartialEq<$ty> for &mut Value {
139 #[inline]
140 fn eq(&self, other: &$ty) -> bool {
141 $eq(*self, *other as _)
142 }
143 }
144 )*)*
145 }
146}
147
148impl_numeric_eq! {
149 eq_i64[i8 i16 i32 i64 isize]
150 eq_u64[u8 u16 u32 u64 usize]
151 eq_f64[f32 f64]
152 eq_bool[bool]
153}
154
155macro_rules! impl_slice_eq {
158 ([$($vars:tt)*], $rhs:ty $(where $ty:ty: $bound:ident)?) => {
159 impl<U, $($vars)*> PartialEq<$rhs> for Array
160 where
161 Value: PartialEq<U>,
162 $($ty: $bound)?
163 {
164 #[inline]
165 fn eq(&self, other: &$rhs) -> bool {
166 let len = self.len();
167 if len != other.len() {
168 return false;
169 }
170 let slf = self.as_ref();
171 let other: &[U] = other.as_ref();
172 slf.iter().zip(other).all(|(a, b)| *a == *b )
173 }
174 }
175
176 impl<U, $($vars)*> PartialEq<$rhs> for Value
177 where
178 Value: PartialEq<U>,
179 $($ty: $bound)?
180 {
181 #[inline]
182 fn eq(&self, other: &$rhs) -> bool {
183 self.as_array().map(|arr| arr == other).unwrap_or(false)
184 }
185 }
186
187
188 impl<U, $($vars)*> PartialEq<Array> for $rhs
189 where
190 Value: PartialEq<U>,
191 $($ty: $bound)?
192 {
193 #[inline]
194 fn eq(&self, other: &Array) -> bool {
195 other == self
196 }
197 }
198
199 impl<U, $($vars)*> PartialEq<Value> for $rhs
200 where
201 Value: PartialEq<U>,
202 $($ty: $bound)?
203 {
204 #[inline]
205 fn eq(&self, other: &Value) -> bool {
206 other == self
207 }
208 }
209 }
210}
211
212impl_slice_eq!([], &[U]);
213impl_slice_eq!([], &mut [U]);
214impl_slice_eq!([], [U]);
215impl_slice_eq!([const N: usize], &[U; N]);
216impl_slice_eq!([const N: usize], [U; N]);
217impl_slice_eq!([], Vec<U>);
218
219use super::{array::Array, object::Object};
222
223macro_rules! impl_container_eq {
224 ($($ty:ty)*) => {
225 $(
226 impl PartialEq<$ty> for Value {
227 #[inline]
228 fn eq(&self, other: &$ty) -> bool {
229 self == &other.0
230 }
231 }
232
233 impl PartialEq<Value> for $ty {
234 #[inline]
235 fn eq(&self, other: &Value) -> bool {
236 other == &self.0
237 }
238 }
239
240 impl PartialEq<$ty> for &Value {
241 #[inline]
242 fn eq(&self, other: &$ty) -> bool {
243 *self == &other.0
244 }
245 }
246
247 impl PartialEq<$ty> for &mut Value {
248 #[inline]
249 fn eq(&self, other: &$ty) -> bool {
250 *self == &other.0
251 }
252 }
253
254 impl PartialEq<Value> for &$ty {
255 #[inline]
256 fn eq(&self, other: &Value) -> bool {
257 other == &self.0
258 }
259 }
260
261 impl PartialEq<Value> for &mut $ty {
262 #[inline]
263 fn eq(&self, other: &Value) -> bool {
264 other == &self.0
265 }
266 }
267
268 )*
269 }
270}
271
272impl_container_eq!(Array Object);
273
274#[cfg(test)]
275mod test {
276 use faststr::FastStr;
277
278 #[test]
279 fn test_slice_eq() {
280 assert_eq!(json!([1, 2, 3]), &[1, 2, 3]);
281 assert_eq!(array![1, 2, 3], &[1, 2, 3]);
282 assert_eq!(json!([1, 2, 3]), array![1, 2, 3].as_slice());
283
284 assert_eq!(json!([1, 2, 3]), vec![1, 2, 3]);
285 assert_eq!(vec![1, 2, 3], array![1, 2, 3]);
286 assert_eq!(array![1, 2, 3], &[1, 2, 3][..]);
287 assert_eq!(json!([1, 2, 3]), array![1, 2, 3].as_slice());
288 }
289
290 #[test]
291 fn test_str_eq() {
292 assert_eq!(json!("123"), FastStr::new("123"));
293 assert_eq!(json!("123"), "123");
294 }
295
296 #[test]
297 fn test_container_eq() {
298 assert_eq!(json!([1, 2, 3]), array![1, 2, 3]);
299 assert_eq!(array![1, 2, 3], json!([1, 2, 3]));
300 assert_eq!(json!({"a": 1, "b": 2}), json!({"b": 2, "a": 1}));
301 assert_eq!(json!({"a": 1, "b": 2}), object! {"a": 1, "b": 2});
302 assert_eq!(object! {"a": 1, "b": 2}, json!({"a": 1, "b": 2}));
303 }
304}