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#[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
159macro_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
223use 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}