1use super::*;
2
3impl Diff for () {
7 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
8 where
9 D: Differ,
10 {
11 out.same(a, b)
12 }
13}
14
15impl<T: ?Sized> Diff for core::marker::PhantomData<T> {
16 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
17 where
18 D: Differ,
19 {
20 out.same(a, b)
21 }
22}
23
24macro_rules! tuple_impl {
28 ($($p:ident / $n:tt),*) => {
29 impl<$($p),*> Diff for ($($p,)*)
30 where
31 $($p: Diff),*
32 {
33 fn diff<DD>(a: &Self, b: &Self, out: DD) -> Result<DD::Ok, DD::Err>
34 where
35 DD: Differ,
36 {
37 let mut out = out.begin_tuple("");
38 $(out.diff_field(&a.$n, &b.$n);)*
39 out.end()
40 }
41 }
42 };
43}
44
45tuple_impl!(A / 0);
46tuple_impl!(A / 0, B / 1);
47tuple_impl!(A / 0, B / 1, C / 2);
48tuple_impl!(A / 0, B / 1, C / 2, D / 3);
49tuple_impl!(A / 0, B / 1, C / 2, D / 3, E / 4);
50tuple_impl!(A / 0, B / 1, C / 2, D / 3, E / 4, F / 5);
51tuple_impl!(A / 0, B / 1, C / 2, D / 3, E / 4, F / 5, G / 6);
52tuple_impl!(A / 0, B / 1, C / 2, D / 3, E / 4, F / 5, G / 6, H / 7);
53tuple_impl!(
54 A / 0,
55 B / 1,
56 C / 2,
57 D / 3,
58 E / 4,
59 F / 5,
60 G / 6,
61 H / 7,
62 I / 8
63);
64
65impl<T> Diff for [T]
69where
70 T: Diff,
71{
72 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
73 where
74 D: Differ,
75 {
76 let mut s = out.begin_seq();
77 s.diff_elements(a, b);
78 s.end()
79 }
80}
81
82macro_rules! array_impl {
83 ($n:tt) => {
84 impl<T> Diff for [T; $n]
85 where
86 T: Diff,
87 {
88 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
89 where
90 D: Differ,
91 {
92 Diff::diff(a as &[T], b as &[T], out)
93 }
94 }
95 };
96}
97
98array_impl!(0);
99array_impl!(1);
100array_impl!(2);
101array_impl!(3);
102array_impl!(4);
103array_impl!(5);
104array_impl!(6);
105array_impl!(7);
106array_impl!(8);
107array_impl!(9);
108array_impl!(10);
109array_impl!(11);
110array_impl!(12);
111array_impl!(13);
112array_impl!(14);
113array_impl!(15);
114array_impl!(16);
115array_impl!(17);
116array_impl!(18);
117array_impl!(19);
118array_impl!(20);
119array_impl!(21);
120array_impl!(22);
121array_impl!(23);
122array_impl!(24);
123array_impl!(25);
124array_impl!(26);
125array_impl!(27);
126array_impl!(28);
127array_impl!(29);
128array_impl!(30);
129array_impl!(31);
130array_impl!(32);
131
132impl<T> Diff for &T
137where
138 T: Diff + ?Sized,
139{
140 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
141 where
142 D: Differ,
143 {
144 Diff::diff(*a, *b, out)
145 }
146}
147
148impl<T> Diff for &mut T
150where
151 T: Diff + ?Sized,
152{
153 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
154 where
155 D: Differ,
156 {
157 Diff::diff(*a, *b, out)
158 }
159}
160
161impl<'a, T: ?Sized + Diff> Diff for core::cell::Ref<'a, T> {
162 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
163 where
164 D: Differ,
165 {
166 Diff::diff(&**a, &**b, out)
167 }
168}
169
170impl<'a, T: ?Sized + Diff> Diff for core::cell::RefMut<'a, T> {
171 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
172 where
173 D: Differ,
174 {
175 Diff::diff(&**a, &**b, out)
176 }
177}
178
179macro_rules! impl_diff_partial_eq {
183 (unsized $ty:ty) => {
186 impl Diff for $ty {
187 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
188 where
189 D: Differ,
190 {
191 if a != b {
192 out.difference(&a, &b)
193 } else {
194 out.same(&a, &b)
195 }
196 }
197 }
198 };
199 ($ty:ty | $p:ident) => {
200 impl<$p> Diff for $ty
201 where
202 $ty: PartialEq + Debug,
203 {
204 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
205 where
206 D: Differ,
207 {
208 if a != b {
209 out.difference(&a, &b)
210 } else {
211 out.same(&a, &b)
212 }
213 }
214 }
215 };
216 ($ty:ty) => {
217 impl Diff for $ty {
218 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
219 where
220 D: Differ,
221 {
222 if a != b {
223 out.difference(a, b)
224 } else {
225 out.same(a, b)
226 }
227 }
228 }
229 };
230}
231
232impl_diff_partial_eq!(bool);
233impl_diff_partial_eq!(char);
234impl_diff_partial_eq!(u8);
235impl_diff_partial_eq!(u16);
236impl_diff_partial_eq!(u32);
237impl_diff_partial_eq!(u64);
238impl_diff_partial_eq!(u128);
239impl_diff_partial_eq!(usize);
240impl_diff_partial_eq!(i8);
241impl_diff_partial_eq!(i16);
242impl_diff_partial_eq!(i32);
243impl_diff_partial_eq!(i64);
244impl_diff_partial_eq!(i128);
245impl_diff_partial_eq!(isize);
246impl_diff_partial_eq!(f32);
247impl_diff_partial_eq!(f64);
248impl_diff_partial_eq!(unsized str);
249impl_diff_partial_eq!(core::cmp::Ordering);
250impl_diff_partial_eq!(core::time::Duration);
251
252impl_diff_partial_eq!(core::ops::Range<T> | T);
256impl_diff_partial_eq!(core::ops::RangeFrom<T> | T);
257impl_diff_partial_eq!(core::ops::RangeFull);
258impl_diff_partial_eq!(core::ops::RangeTo<T> | T);
259impl_diff_partial_eq!(core::ops::RangeToInclusive<T> | T);
260
261impl<T: ?Sized> Diff for *const T {
263 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
264 where
265 D: Differ,
266 {
267 if a != b {
268 out.difference(a, b)
269 } else {
270 out.same(a, b)
271 }
272 }
273}
274
275impl<T: ?Sized> Diff for *mut T {
277 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
278 where
279 D: Differ,
280 {
281 if a != b {
282 out.difference(a, b)
283 } else {
284 out.same(a, b)
285 }
286 }
287}
288
289impl<T: Copy + Diff> Diff for core::cell::Cell<T> {
295 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
296 where
297 D: Differ,
298 {
299 let mut out = out.begin_struct("Cell");
300 out.diff_field("value", &a.get(), &b.get());
301 out.end()
302 }
303}
304
305impl<T: ?Sized + Diff> Diff for core::mem::ManuallyDrop<T> {
306 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
307 where
308 D: Differ,
309 {
310 let mut out = out.begin_struct("ManuallyDrop");
311 out.diff_field("value", &*a, &*b);
312 out.end()
313 }
314}
315
316impl<T: Diff> Diff for core::num::Wrapping<T> {
317 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
318 where
319 D: Differ,
320 {
321 Diff::diff(&a.0, &b.0, out)
322 }
323}
324
325impl<T: ?Sized + Diff> Diff for core::cell::RefCell<T> {
327 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
328 where
329 D: Differ,
330 {
331 let mut out = out.begin_struct("RefCell");
332 out.diff_field("value", &*a.borrow(), &*b.borrow());
333 out.end()
334 }
335}
336
337impl<T: Diff> Diff for core::option::Option<T> {
338 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
339 where
340 D: Differ,
341 {
342 match (a, b) {
343 (None, None) => out.same(a, b),
344 (Some(a), Some(b)) => {
345 let mut out = out.begin_tuple_variant("Option", "Some");
346 out.diff_field(a, b);
347 out.end()
348 }
349 _ => out.difference(a, b),
350 }
351 }
352}
353
354impl<T: Diff, E: Diff> Diff for core::result::Result<T, E> {
355 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
356 where
357 D: Differ,
358 {
359 match (a, b) {
360 (Ok(a), Ok(b)) => {
361 let mut out = out.begin_tuple_variant("Result", "Ok");
362 out.diff_field(a, b);
363 out.end()
364 }
365 (Err(a), Err(b)) => {
366 let mut out = out.begin_tuple_variant("Result", "Err");
367 out.diff_field(a, b);
368 out.end()
369 }
370 _ => out.difference(a, b),
371 }
372 }
373}
374
375#[cfg(test)]
376mod tests {
377 use super::*;
378
379 #[allow(unused)]
380 #[derive(Clone, Debug)]
381 pub enum TestEnum {
382 First,
383 Second,
384 Struct { a: usize, b: bool },
385 }
386
387 impl Diff for TestEnum {
388 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
389 where
390 D: Differ,
391 {
392 match (a, b) {
393 (TestEnum::First, TestEnum::First) => out.same(a, b),
394 (TestEnum::Second, TestEnum::Second) => out.same(a, b),
395 (
396 TestEnum::Struct { a: aa, b: ab },
397 TestEnum::Struct { a: ba, b: bb },
398 ) => {
399 let mut s = out.begin_struct_variant("TestEnum", "Struct");
400 s.diff_field("a", &aa, &ba);
401 s.diff_field("b", &ab, &bb);
402 s.end()
403 }
404 _ => out.difference(a, b),
405 }
406 }
407 }
408
409 #[derive(Clone, Debug)]
410 pub struct TestStruct {
411 pub distance: usize,
412 pub silly: bool,
413 }
414
415 impl Diff for TestStruct {
416 fn diff<D>(a: &Self, b: &Self, out: D) -> Result<D::Ok, D::Err>
417 where
418 D: Differ,
419 {
420 let mut s = out.begin_struct("TestStruct");
421 s.diff_field("distance", &a.distance, &b.distance);
422 s.diff_field("silly", &a.silly, &b.silly);
423 s.end()
424 }
425 }
426}