1use super::utils::find_match;
2use super::*;
3use serde::{Deserialize, Serialize};
4use std::borrow::Cow;
5use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
6use std::fmt::{Debug, Formatter, Result as FmtResult};
7use std::hash::Hash;
8use std::marker::PhantomData;
9use std::ops::Deref;
10use std::path::PathBuf;
11use std::rc::Rc;
12use std::sync::Arc;
13
14impl Diff for bool {
15 type Repr = Option<bool>;
16
17 fn diff(&self, other: &Self) -> Self::Repr {
18 if self != other {
19 Some(*other)
20 } else {
21 None
22 }
23 }
24
25 fn apply(&mut self, diff: &Self::Repr) {
26 if let Some(diff) = diff {
27 *self = *diff;
28 }
29 }
30
31 fn identity() -> Self {
32 false
33 }
34}
35
36impl<T> Diff for Arc<T>
37where
38 T: Diff + Clone,
39{
40 type Repr = T::Repr;
41
42 fn diff(&self, other: &Self) -> Self::Repr {
43 self.deref().diff(other.deref())
44 }
45
46 fn apply(&mut self, diff: &Self::Repr) {
47 match Arc::get_mut(self) {
48 Some(m) => m.apply(diff),
49 None => {
50 let mut x = (**self).clone();
51 x.apply(diff);
52 *self = Arc::new(x);
53 }
54 }
55 }
56
57 fn identity() -> Self {
58 Arc::new(T::identity())
59 }
60}
61
62impl<T> Diff for Box<T>
63where
64 T: Diff,
65{
66 type Repr = Box<T::Repr>;
67
68 fn diff(&self, other: &Self) -> Self::Repr {
69 Box::new(self.deref().diff(other.deref()))
70 }
71
72 fn apply(&mut self, diff: &Self::Repr) {
73 self.as_mut().apply(diff.as_ref())
74 }
75
76 fn identity() -> Self {
77 Box::new(T::identity())
78 }
79}
80
81impl<T> Diff for Rc<T>
82where
83 T: Diff + Clone,
84{
85 type Repr = T::Repr;
86
87 fn diff(&self, other: &Self) -> Self::Repr {
88 self.deref().diff(other.deref())
89 }
90
91 fn apply(&mut self, diff: &Self::Repr) {
92 match Rc::get_mut(self) {
93 Some(m) => m.apply(diff),
94 None => {
95 let mut x = (**self).clone();
96 x.apply(diff);
97 *self = Rc::new(x);
98 }
99 }
100 }
101
102 fn identity() -> Self {
103 Rc::new(T::identity())
104 }
105}
106
107macro_rules! diff_tuple {
108 (($($ty:ident),*), ($($access:tt),*)) => {
109 impl<$($ty),*> Diff for ($($ty),*,)
110 where $($ty: Diff),*
111 {
112 type Repr = ($(<$ty>::Repr),*,);
113
114 fn diff(&self, other: &Self) -> Self::Repr {
115 ($(self.$access.diff(&other.$access)),*,)
116 }
117
118 fn apply(&mut self, diff: &Self::Repr) {
119 $(self.$access.apply(&diff.$access));*;
120 }
121
122 fn identity() -> Self {
123 ($(<$ty>::identity()),*,)
124 }
125 }
126 }
127}
128
129diff_tuple!((A), (0));
130diff_tuple!((A, B), (0, 1));
131diff_tuple!((A, B, C), (0, 1, 2));
132diff_tuple!((A, B, C, D), (0, 1, 2, 3));
133diff_tuple!((A, B, C, D, F), (0, 1, 2, 3, 4));
134diff_tuple!((A, B, C, D, F, G), (0, 1, 2, 3, 4, 5));
135diff_tuple!((A, B, C, D, F, G, H), (0, 1, 2, 3, 4, 5, 6));
136diff_tuple!((A, B, C, D, F, G, H, I), (0, 1, 2, 3, 4, 5, 6, 7));
137diff_tuple!((A, B, C, D, F, G, H, I, J), (0, 1, 2, 3, 4, 5, 6, 7, 8));
138diff_tuple!(
139 (A, B, C, D, F, G, H, I, J, K),
140 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
141);
142diff_tuple!(
143 (A, B, C, D, F, G, H, I, J, K, L),
144 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
145);
146diff_tuple!(
147 (A, B, C, D, F, G, H, I, J, K, L, M),
148 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
149);
150diff_tuple!(
151 (A, B, C, D, F, G, H, I, J, K, L, M, N),
152 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
153);
154diff_tuple!(
155 (A, B, C, D, F, G, H, I, J, K, L, M, N, O),
156 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
157);
158diff_tuple!(
159 (A, B, C, D, F, G, H, I, J, K, L, M, N, O, P),
160 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14)
161);
162diff_tuple!(
163 (A, B, C, D, F, G, H, I, J, K, L, M, N, O, P, Q),
164 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
165);
166diff_tuple!(
167 (A, B, C, D, F, G, H, I, J, K, L, M, N, O, P, Q, R),
168 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
169);
170diff_tuple!(
171 (A, B, C, D, F, G, H, I, J, K, L, M, N, O, P, Q, R, S),
172 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)
173);
174
175macro_rules! diff_int {
176 ($($ty:ty),*) => {
177 $(impl Diff for $ty {
178 type Repr = $ty;
179
180 fn diff(&self, other: &Self) -> Self::Repr {
181 other.wrapping_sub(*self)
182 }
183
184 fn apply(&mut self, diff: &Self::Repr) {
185 *self = self.wrapping_add(*diff);
186 }
187
188 fn identity() -> $ty {
189 0
190 }
191 })*
192 };
193}
194
195macro_rules! diff_float {
196 ($($ty:ty),*) => {
197 $(impl Diff for $ty {
198 type Repr = $ty;
199
200 fn diff(&self, other: &Self) -> Self::Repr {
201 other - self
202 }
203
204 fn apply(&mut self, diff: &Self::Repr){
205 *self += diff;
206 }
207
208 fn identity() -> $ty {
209 0.0
210 }
211 })*
212 };
213}
214
215diff_int!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
216
217macro_rules! diff_non_zero_int {
218 ($($ty:ty, $original:ty),*) => {
219 #[cfg(feature = "impl_num")]
220 $(impl Diff for $ty {
221 type Repr = $original;
222
223 fn diff(&self, other: &Self) -> Self::Repr {
224 other.get().wrapping_sub(self.get())
225 }
226
227 fn apply(&mut self, diff: &Self::Repr) {
228 *self = <$ty>::new(self.get() + *diff).unwrap();
229 }
230
231 fn identity() -> $ty {
232 use num::traits::One;
233 <$ty>::new(<$original>::one()).unwrap()
234 }
235 })*
236 };
237}
238
239#[cfg(feature = "impl_num")]
240use std::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
241
242diff_non_zero_int!(NonZeroU8, u8);
243diff_non_zero_int!(NonZeroU16, u16);
244diff_non_zero_int!(NonZeroU32, u32);
245diff_non_zero_int!(NonZeroU64, u64);
246diff_non_zero_int!(NonZeroU128, u128);
247diff_non_zero_int!(NonZeroUsize, usize);
248
249diff_float!(f32, f64);
250
251impl Diff for char {
252 type Repr = Option<char>;
253
254 fn diff(&self, other: &Self) -> Self::Repr {
255 if self != other {
256 Some(*other)
257 } else {
258 None
259 }
260 }
261
262 fn apply(&mut self, diff: &Self::Repr) {
263 if let Some(diff) = diff {
264 *self = *diff
265 }
266 }
267
268 fn identity() -> Self {
269 '\x00'
270 }
271}
272
273impl Diff for String {
274 type Repr = Option<String>;
275
276 fn diff(&self, other: &Self) -> Self::Repr {
277 if self != other {
278 Some(other.clone())
279 } else {
280 None
281 }
282 }
283
284 fn apply(&mut self, diff: &Self::Repr) {
285 if let Some(diff) = diff {
286 *self = diff.clone()
287 }
288 }
289
290 fn identity() -> Self {
291 String::new()
292 }
293}
294
295impl Diff for PathBuf {
296 type Repr = Option<PathBuf>;
297
298 fn diff(&self, other: &Self) -> Self::Repr {
299 if self != other {
300 Some(other.clone())
301 } else {
302 None
303 }
304 }
305
306 fn apply(&mut self, diff: &Self::Repr) {
307 if let Some(diff) = diff {
308 *self = diff.clone()
309 }
310 }
311
312 fn identity() -> Self {
313 PathBuf::new()
314 }
315}
316
317impl<'a> Diff for &'a str {
318 type Repr = Option<&'a str>;
319
320 fn diff(&self, other: &Self) -> Self::Repr {
321 if self != other {
322 Some(other)
323 } else {
324 None
325 }
326 }
327
328 fn apply(&mut self, diff: &Self::Repr) {
329 if let Some(diff) = diff {
330 *self = diff
331 }
332 }
333
334 fn identity() -> Self {
335 Default::default()
336 }
337}
338
339impl<T> Diff for Cow<'_, T>
340where
341 T: ToOwned + PartialEq + ?Sized,
342 <T as ToOwned>::Owned: Clone + Default,
343{
344 type Repr = Option<<T as ToOwned>::Owned>;
348
349 fn diff(&self, other: &Self) -> Self::Repr {
350 if self != other {
351 Some(other.clone().into_owned())
352 } else {
353 None
354 }
355 }
356
357 fn apply(&mut self, diff: &Self::Repr) {
358 if let Some(diff) = diff {
359 *self = Cow::Owned(diff.clone())
360 }
361 }
362
363 fn identity() -> Self {
364 Default::default()
365 }
366}
367
368#[derive(Serialize, Deserialize)]
369pub enum OptionDiff<T: Diff> {
370 Some(T::Repr),
371 None,
372 NoChange,
373}
374
375impl<T: Diff + PartialEq> Diff for Option<T> {
376 type Repr = OptionDiff<T>;
377
378 fn diff(&self, other: &Self) -> Self::Repr {
379 match (self, other) {
380 (Some(value), Some(other_value)) => {
381 if value == other_value {
382 OptionDiff::NoChange
383 } else {
384 OptionDiff::Some(value.diff(other_value))
385 }
386 }
387 (Some(_), None) => OptionDiff::None,
388 (None, Some(other_value)) => OptionDiff::Some(T::identity().diff(other_value)),
389 (None, None) => OptionDiff::NoChange,
390 }
391 }
392
393 fn apply(&mut self, diff: &Self::Repr) {
394 match diff {
395 OptionDiff::None => *self = None,
396 OptionDiff::Some(change) => {
397 if let Some(value) = self {
398 value.apply(change);
399 } else {
400 *self = Some(T::identity().apply_new(change))
401 }
402 }
403 _ => {}
404 }
405 }
406
407 fn identity() -> Self {
408 None
409 }
410}
411
412impl<T: Diff> Debug for OptionDiff<T>
413where
414 T::Repr: Debug,
415{
416 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
417 match &self {
418 OptionDiff::Some(change) => f.debug_tuple("Some").field(change).finish(),
419 OptionDiff::None => write!(f, "None"),
420 OptionDiff::NoChange => write!(f, "NoChange"),
421 }
422 }
423}
424
425impl<T: Diff> PartialEq for OptionDiff<T>
426where
427 T::Repr: PartialEq,
428{
429 fn eq(&self, other: &Self) -> bool {
430 match (self, other) {
431 (OptionDiff::Some(a), OptionDiff::Some(b)) => a == b,
432 (OptionDiff::None, OptionDiff::None) => true,
433 (OptionDiff::NoChange, OptionDiff::NoChange) => true,
434 _ => false,
435 }
436 }
437}
438
439impl<T: Diff> Clone for OptionDiff<T>
440where
441 T::Repr: Clone,
442{
443 fn clone(&self) -> Self {
444 match self {
445 OptionDiff::Some(a) => OptionDiff::Some(a.clone()),
446 OptionDiff::None => OptionDiff::None,
447 OptionDiff::NoChange => OptionDiff::NoChange,
448 }
449 }
450}
451
452#[derive(Serialize, Deserialize)]
454#[serde(bound(serialize = "V::Repr: Serialize, K: Serialize"))]
455#[serde(bound(deserialize = "V::Repr: Deserialize<'de>, K: Deserialize<'de>"))]
456pub struct HashMapDiff<K: Hash + Eq, V: Diff> {
457 pub altered: HashMap<K, <V as Diff>::Repr>,
459 pub removed: HashSet<K>,
461}
462
463#[derive(Serialize, Deserialize)]
465#[serde(bound(serialize = "V::Repr: Serialize, K: Serialize"))]
466#[serde(bound(deserialize = "V::Repr: Deserialize<'de>, K: Deserialize<'de>"))]
467pub struct BTreeMapDiff<K: Ord + Eq, V: Diff> {
468 pub altered: BTreeMap<K, <V as Diff>::Repr>,
470 pub removed: BTreeSet<K>,
472}
473
474macro_rules! diff_map {
475 ($ty: ident, $diffty: ident, $diffkey: ident, ($($constraints:tt)*)) => {
476 impl<K: $($constraints)*, V: Diff> Diff for $ty<K, V>
477 where
478 K: Clone,
479 V: PartialEq,
480 {
481 type Repr = $diffty<K, V>;
482
483 fn diff(&self, other: &Self) -> Self::Repr {
484 let mut diff = $diffty {
485 altered: $ty::new(),
486 removed: $diffkey::new(),
487 };
488 for (key, value) in self {
490 if let Some(other_value) = other.get(key) {
491 if value != other_value {
493 diff.altered.insert(key.clone(), value.diff(other_value));
494 }
495 } else {
496 diff.removed.insert(key.clone());
497 }
498 }
499 for (key, value) in other {
500 if let None = self.get(key) {
501 diff.altered.insert(key.clone(), V::identity().diff(value));
502 }
503 }
504 diff
505 }
506
507 fn apply(&mut self, diff: &Self::Repr) {
509 diff.removed.iter().for_each(|del| {
510 self.remove(del);
511 });
512 for (key, change) in &diff.altered {
513 if let Some(original) = self.get_mut(key) {
514 original.apply(change);
515 } else {
516 self.insert(key.clone(), V::identity().apply_new(change));
517 }
518 }
519 }
520
521 fn identity() -> Self {
522 $ty::new()
523 }
524 }
525
526 impl<K: $($constraints)*, V: Diff> Debug for $diffty<K, V>
527 where
528 K: Debug,
529 V::Repr: Debug,
530 {
531 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
532 f.debug_struct(stringify!($diffty))
533 .field("altered", &self.altered)
534 .field("removed", &self.removed)
535 .finish()
536 }
537 }
538
539 impl<K: $($constraints)*, V: Diff> PartialEq for $diffty<K, V>
540 where
541 V::Repr: PartialEq,
542 {
543 fn eq(&self, other: &Self) -> bool {
544 self.altered == other.altered && self.removed == other.removed
545 }
546 }
547
548 impl<K: $($constraints)*, V: Diff> Clone for $diffty<K, V>
549 where
550 K: Clone,
551 V::Repr: Clone,
552 {
553 fn clone(&self) -> Self {
554 $diffty {
555 altered: self.altered.clone(),
556 removed: self.removed.clone(),
557 }
558 }
559 }
560 }
561}
562
563diff_map!(HashMap, HashMapDiff, HashSet, (Hash + Eq));
564diff_map!(BTreeMap, BTreeMapDiff, BTreeSet, (Ord));
565
566#[derive(Serialize, Deserialize)]
568#[serde(bound(serialize = "T: Serialize"))]
569#[serde(bound(deserialize = "T: Deserialize<'de>"))]
570pub struct HashSetDiff<T: Hash + Eq> {
571 pub added: HashSet<T>,
573 pub removed: HashSet<T>,
575}
576
577#[derive(Serialize, Deserialize)]
579#[serde(bound(serialize = "T: Serialize"))]
580#[serde(bound(deserialize = "T: Deserialize<'de>"))]
581pub struct BTreeSetDiff<T: Ord + Eq> {
582 pub added: BTreeSet<T>,
584 pub removed: BTreeSet<T>,
586}
587
588macro_rules! diff_set {
589 ($ty: ident, $diffty: ident, $diffkey: ident, ($($constraints:tt)*)) => {
590 impl<T: $($constraints)*> Diff for $ty<T>
591 where
592 T: Clone,
593 {
594 type Repr = $diffty<T>;
595
596 fn diff(&self, other: &Self) -> Self::Repr {
597 let mut diff = $diffty {
598 added: $diffkey::new(),
599 removed: $diffkey::new(),
600 };
601 for value in self {
602 if !other.contains(value) {
603 diff.removed.insert(value.clone());
604 }
605 }
606 for value in other {
607 if !self.contains(value) {
608 diff.added.insert(value.clone());
609 }
610 }
611 diff
612 }
613
614 fn apply(&mut self, diff: &Self::Repr) {
616 diff.removed.iter().for_each(|del| {
617 self.remove(del);
618 });
619 diff.added.iter().for_each(|add| {
620 self.insert(add.clone());
621 });
622 }
623
624 fn identity() -> Self {
625 $ty::new()
626 }
627 }
628
629 impl<T: $($constraints)*> Debug for $diffty<T>
630 where
631 T: Debug,
632 {
633 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
634 f.debug_struct(stringify!($diffty))
635 .field("added", &self.added)
636 .field("removed", &self.removed)
637 .finish()
638 }
639 }
640
641 impl<T: $($constraints)*> PartialEq for $diffty<T>
642 where
643 T: PartialEq,
644 {
645 fn eq(&self, other: &Self) -> bool {
646 self.added == other.added && self.removed == other.removed
647 }
648 }
649
650 impl<T: $($constraints)*> Clone for $diffty<T>
651 where
652 T: Clone,
653 {
654 fn clone(&self) -> Self {
655 $diffty {
656 added: self.added.clone(),
657 removed: self.removed.clone(),
658 }
659 }
660 }
661 }
662}
663
664diff_set!(HashSet, HashSetDiff, HashSet, (Hash + Eq));
665diff_set!(BTreeSet, BTreeSetDiff, BTreeSet, (Ord));
666
667#[derive(Serialize, Deserialize)]
669#[serde(bound(serialize = "T::Repr: Serialize"))]
670#[serde(bound(deserialize = "T::Repr: Deserialize<'de>"))]
671pub enum VecDiffType<T: Diff> {
672 Removed { index: usize, len: usize },
673 Altered { index: usize, changes: Vec<T::Repr> },
674 Inserted { index: usize, changes: Vec<T::Repr> },
675}
676
677#[derive(Serialize, Deserialize)]
679#[serde(bound(serialize = "T::Repr: Serialize"))]
680#[serde(bound(deserialize = "T::Repr: Deserialize<'de>"))]
681pub struct VecDiff<T: Diff>(pub Vec<VecDiffType<T>>);
682
683impl<T: Diff + PartialEq> Diff for Vec<T> {
684 type Repr = VecDiff<T>;
685
686 fn diff(&self, other: &Self) -> Self::Repr {
687 let mut changes = Vec::new();
688 let mut pos_x = 0;
689 let mut pos_y = 0;
690 loop {
691 let (is_match, deletions, insertions) = find_match(&self[pos_x..], &other[pos_y..]);
692
693 if deletions == 0 || insertions == 0 {
695 if deletions > 0 {
696 changes.push(VecDiffType::Removed {
697 index: pos_x,
698 len: deletions,
699 });
700 } else if insertions > 0 {
701 changes.push(VecDiffType::Inserted {
702 index: pos_x,
703 changes: other[pos_y..pos_y + insertions]
704 .iter()
705 .map(|new| T::identity().diff(new))
706 .collect(),
707 });
708 }
709 } else if deletions == insertions {
710 changes.push(VecDiffType::Altered {
711 index: pos_x,
712 changes: self[pos_x..pos_x + deletions]
713 .iter()
714 .zip(other[pos_y..pos_y + insertions].iter())
715 .map(|(a, b)| a.diff(b))
716 .collect(),
717 });
718 } else if deletions > insertions {
719 changes.push(VecDiffType::Altered {
720 index: pos_x,
721 changes: self[pos_x..pos_x + insertions]
722 .iter()
723 .zip(other[pos_y..pos_y + insertions].iter())
724 .map(|(a, b)| a.diff(b))
725 .collect(),
726 });
727 changes.push(VecDiffType::Removed {
728 index: pos_x + insertions,
729 len: deletions - insertions,
730 });
731 } else {
732 changes.push(VecDiffType::Altered {
733 index: pos_x,
734 changes: self[pos_x..pos_x + deletions]
735 .iter()
736 .zip(other[pos_y..pos_y + deletions].iter())
737 .map(|(a, b)| a.diff(b))
738 .collect(),
739 });
740 changes.push(VecDiffType::Inserted {
741 index: pos_x + deletions,
742 changes: other[pos_y + deletions..pos_y + insertions]
743 .iter()
744 .map(|new| T::identity().diff(new))
745 .collect(),
746 });
747 }
748
749 if is_match {
750 pos_x += deletions + 1;
751 pos_y += insertions + 1;
752 } else {
753 break;
754 }
755 }
756 VecDiff(changes)
757 }
758
759 fn apply(&mut self, diff: &Self::Repr) {
760 let mut relative_index = 0_isize;
761 for change in &diff.0 {
762 match change {
763 VecDiffType::Removed { index, len } => {
764 let index = (*index as isize + relative_index) as usize;
765 self.drain(index..index + len);
766 relative_index -= *len as isize;
767 }
768 VecDiffType::Inserted { index, changes } => {
769 let index = (*index as isize + relative_index) as usize;
770 self.splice(
771 index..index,
772 changes.iter().map(|d| T::identity().apply_new(d)),
773 );
774 relative_index += changes.len() as isize;
775 }
776 VecDiffType::Altered { index, changes } => {
777 let index = (*index as isize + relative_index) as usize;
778 let range = index..index + changes.len();
779 for (value, diff) in self[range].iter_mut().zip(changes.iter()) {
780 value.apply(diff);
781 }
782 }
783 }
784 }
785 }
786
787 fn identity() -> Self {
788 Vec::new()
789 }
790}
791
792impl<T: Diff> Debug for VecDiffType<T>
793where
794 T::Repr: Debug,
795{
796 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
797 match self {
798 VecDiffType::Removed { index, len } => f
799 .debug_struct("Removed")
800 .field("index", index)
801 .field("len", len)
802 .finish(),
803 VecDiffType::Altered { index, changes } => f
804 .debug_struct("Altered")
805 .field("index", index)
806 .field("changes", changes)
807 .finish(),
808 VecDiffType::Inserted { index, changes } => f
809 .debug_struct("Inserted")
810 .field("index", index)
811 .field("changes", changes)
812 .finish(),
813 }
814 }
815}
816
817impl<T: Diff> PartialEq for VecDiffType<T>
818where
819 T::Repr: PartialEq,
820{
821 fn eq(&self, other: &Self) -> bool {
822 match (self, other) {
823 (
824 VecDiffType::Removed { index, len },
825 VecDiffType::Removed {
826 index: ref index_,
827 len: ref len_,
828 },
829 ) => index == index_ && len == len_,
830 (
831 VecDiffType::Altered { index, changes },
832 VecDiffType::Altered {
833 index: ref index_,
834 changes: ref changes_,
835 },
836 ) => index == index_ && changes == changes_,
837 (
838 VecDiffType::Inserted { index, changes },
839 VecDiffType::Inserted {
840 index: ref index_,
841 changes: ref changes_,
842 },
843 ) => index == index_ && changes == changes_,
844 _ => false,
845 }
846 }
847}
848
849impl<T: Diff> Clone for VecDiffType<T>
850where
851 T::Repr: Clone,
852{
853 fn clone(&self) -> Self {
854 match self {
855 VecDiffType::Removed { index, len } => VecDiffType::Removed {
856 index: *index,
857 len: *len,
858 },
859 VecDiffType::Altered { index, changes } => VecDiffType::Altered {
860 index: *index,
861 changes: changes.clone(),
862 },
863 VecDiffType::Inserted { index, changes } => VecDiffType::Inserted {
864 index: *index,
865 changes: changes.clone(),
866 },
867 }
868 }
869}
870
871impl<T: Diff> Debug for VecDiff<T>
872where
873 T::Repr: Debug,
874{
875 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
876 f.debug_list().entries(self.0.iter()).finish()
877 }
878}
879
880impl<T: Diff> PartialEq for VecDiff<T>
881where
882 T::Repr: PartialEq,
883{
884 fn eq(&self, other: &Self) -> bool {
885 self.0 == other.0
886 }
887}
888
889impl<T: Diff> Clone for VecDiff<T>
890where
891 T::Repr: Clone,
892{
893 fn clone(&self) -> Self {
894 Self(self.0.clone())
895 }
896}
897
898#[derive(Serialize, Deserialize)]
900#[serde(bound(serialize = "T::Repr: Serialize"))]
901#[serde(bound(deserialize = "T::Repr: Deserialize<'de>"))]
902pub struct ArrayDiffType<T: Diff> {
903 pub index: usize,
904 pub change: T::Repr,
905}
906
907#[derive(Serialize, Deserialize)]
909#[serde(bound(serialize = "T::Repr: Serialize"))]
910#[serde(bound(deserialize = "T::Repr: Deserialize<'de>"))]
911pub struct ArrayDiff<T: Diff>(pub Vec<ArrayDiffType<T>>);
912
913impl<T: Diff + PartialEq, const N: usize> Diff for [T; N] {
914 type Repr = ArrayDiff<T>;
915
916 fn diff(&self, other: &Self) -> Self::Repr {
917 ArrayDiff(
918 self.iter()
919 .zip(other.iter())
920 .enumerate()
921 .filter_map(|(index, (self_el, other_el))| {
922 self_el.ne(other_el).then(|| ArrayDiffType {
923 index,
924 change: self_el.diff(other_el),
925 })
926 })
927 .collect(),
928 )
929 }
930
931 fn apply(&mut self, diff: &Self::Repr) {
932 for ArrayDiffType { index, change } in &diff.0 {
933 self[*index].apply(change);
934 }
935 }
936
937 fn identity() -> Self {
938 std::array::from_fn(|_| T::identity())
939 }
940}
941
942impl<T: Diff> Debug for ArrayDiffType<T>
943where
944 T::Repr: Debug,
945{
946 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
947 f.debug_struct("ArrayDiffType")
948 .field("index", &self.index)
949 .field("change", &self.change)
950 .finish()
951 }
952}
953
954impl<T: Diff> PartialEq for ArrayDiffType<T>
955where
956 T::Repr: PartialEq,
957{
958 fn eq(&self, other: &Self) -> bool {
959 self.index == other.index && self.change == other.change
960 }
961}
962
963impl<T: Diff> Clone for ArrayDiffType<T>
964where
965 T::Repr: Clone,
966{
967 fn clone(&self) -> Self {
968 Self {
969 index: self.index,
970 change: self.change.clone(),
971 }
972 }
973}
974
975impl<T: Diff> Debug for ArrayDiff<T>
976where
977 T::Repr: Debug,
978{
979 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
980 f.debug_list().entries(self.0.iter()).finish()
981 }
982}
983
984impl<T: Diff> PartialEq for ArrayDiff<T>
985where
986 T::Repr: PartialEq,
987{
988 fn eq(&self, other: &Self) -> bool {
989 self.0 == other.0
990 }
991}
992
993impl<T: Diff> Clone for ArrayDiff<T>
994where
995 T::Repr: Clone,
996{
997 fn clone(&self) -> Self {
998 Self(self.0.clone())
999 }
1000}
1001
1002impl<T> Diff for PhantomData<T> {
1003 type Repr = PhantomData<T>;
1004
1005 fn diff(&self, _other: &Self) -> Self::Repr {
1006 PhantomData::default()
1007 }
1008
1009 fn apply(&mut self, _diff: &Self::Repr) {}
1010
1011 fn identity() -> Self {
1012 PhantomData::default()
1013 }
1014}