1use super::{Diff, EventQueue, Patch, PatchError, PathBuilder};
4use crate::event::ParamData;
5
6macro_rules! sequence_diff {
7 ($gen:ident, $ty:ty) => {
8 impl<$gen: Diff> Diff for $ty {
9 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
10 for (i, item) in self.iter().enumerate() {
11 item.diff(&baseline[i], path.with(i as u32), event_queue);
12 }
13 }
14 }
15
16 impl<$gen: Patch> Patch for $ty {
17 type Patch = (usize, $gen::Patch);
18
19 fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
20 let first = *path.first().ok_or(PatchError::InvalidPath)?;
21 let inner = $gen::patch(data, &path[1..])?;
22
23 Ok((first as usize, inner))
24 }
25
26 fn apply(&mut self, patch: Self::Patch) {
27 self[patch.0].apply(patch.1);
28 }
29 }
30 };
31}
32
33sequence_diff!(T, Vec<T>);
34sequence_diff!(T, Box<[T]>);
35sequence_diff!(T, [T]);
36
37impl<T: Diff, const LEN: usize> Diff for [T; LEN] {
38 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
39 for (i, item) in self.iter().enumerate() {
40 item.diff(&baseline[i], path.with(i as u32), event_queue);
41 }
42 }
43}
44
45impl<T: Patch, const LEN: usize> Patch for [T; LEN] {
46 type Patch = (usize, T::Patch);
47
48 fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
49 let first = *path.first().ok_or(PatchError::InvalidPath)? as usize;
50 if first >= LEN {
51 return Err(PatchError::InvalidPath);
52 }
53 let inner = T::patch(data, &path[1..])?;
54
55 Ok((first, inner))
56 }
57
58 fn apply(&mut self, patch: Self::Patch) {
59 self[patch.0].apply(patch.1);
60 }
61}
62
63macro_rules! tuple_diff {
64 ($tup:ident, $($gen:ident, $base:ident, $index:literal),*) => {
65 pub enum $tup<$($gen: Patch),*> {
66 $($gen($gen::Patch)),*
67 }
68
69 #[allow(non_snake_case, unused_variables)]
70 impl<$($gen: Diff),*> Diff for ($($gen,)*) {
71 fn diff<EQ: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut EQ) {
72 let ($($gen,)*) = self;
73 let ($($base,)*) = baseline;
74
75 $(
76 $gen.diff($base, path.with($index), event_queue);
77 )*
78 }
79 }
80
81 #[allow(non_snake_case, unused_variables)]
82 impl<$($gen: Patch),*> Patch for ($($gen,)*) {
83 type Patch = $tup<$($gen),*>;
84
85 fn patch(data: &ParamData, path: &[u32]) -> Result<Self::Patch, PatchError> {
86 match path {
87 $(
88 [$index, tail @ ..] => Ok($tup::$gen($gen::patch(data, tail)?)),
89 )*
90 _ => Err(PatchError::InvalidPath),
91 }
92 }
93
94 fn apply(&mut self, patch: Self::Patch) {
95 let ($($gen,)*) = self;
96
97 match patch {
98 $(
99 $tup::$gen(p) => $gen.apply(p)
100 ),*
101 }
102 }
103 }
104 };
105}
106
107tuple_diff!(Tuple1, A, A1, 0);
108tuple_diff!(Tuple2, A, A1, 0, B, B1, 1);
109tuple_diff!(Tuple3, A, A1, 0, B, B1, 1, C, C1, 2);
110tuple_diff!(Tuple4, A, A1, 0, B, B1, 1, C, C1, 2, D, D1, 3);
111tuple_diff!(Tuple5, A, A1, 0, B, B1, 1, C, C1, 2, D, D1, 3, E, E1, 4);
112tuple_diff!(Tuple6, A, A1, 0, B, B1, 1, C, C1, 2, D, D1, 3, E, E1, 4, F, F1, 5);
113tuple_diff!(Tuple7, A, A1, 0, B, B1, 1, C, C1, 2, D, D1, 3, E, E1, 4, F, F1, 5, G, G1, 6);
114tuple_diff!(Tuple8, A, A1, 0, B, B1, 1, C, C1, 2, D, D1, 3, E, E1, 4, F, F1, 5, G, G1, 6, H, H1, 7);