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 fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError> {
18 let first = path.first().ok_or(PatchError::InvalidPath)?;
19 let target = self
20 .get_mut(*first as usize)
21 .ok_or(PatchError::InvalidPath)?;
22
23 target.patch(data, &path[1..])
24 }
25 }
26 };
27}
28
29sequence_diff!(T, Vec<T>);
30sequence_diff!(T, Box<[T]>);
31sequence_diff!(T, [T]);
32
33impl<T: Diff, const LEN: usize> Diff for [T; LEN] {
34 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
35 for (i, item) in self.iter().enumerate() {
36 item.diff(&baseline[i], path.with(i as u32), event_queue);
37 }
38 }
39}
40
41impl<T: Patch, const LEN: usize> Patch for [T; LEN] {
42 fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError> {
43 let first = path.first().ok_or(PatchError::InvalidPath)?;
44 let target = self
45 .get_mut(*first as usize)
46 .ok_or(PatchError::InvalidPath)?;
47
48 target.patch(data, &path[1..])
49 }
50}
51
52macro_rules! tuple_diff {
53 ($($gen:ident, $base:ident, $index:literal),*) => {
54 #[allow(non_snake_case, unused_variables)]
55 impl<$($gen: Diff),*> Diff for ($($gen,)*) {
56 fn diff<E: EventQueue>(&self, baseline: &Self, path: PathBuilder, event_queue: &mut E) {
57 let ($($gen,)*) = self;
58 let ($($base,)*) = baseline;
59
60 $(
61 $gen.diff($base, path.with($index), event_queue);
62 )*
63 }
64 }
65
66 #[allow(non_snake_case, unused_variables)]
67 impl<$($gen: Patch),*> Patch for ($($gen,)*) {
68 fn patch(&mut self, data: &ParamData, path: &[u32]) -> Result<(), PatchError> {
69 let ($($gen,)*) = self;
70
71 match path {
72 $(
73 [$index, tail @ ..] => $gen.patch(data, tail),
74 )*
75 _ => Err(PatchError::InvalidPath),
76 }
77 }
78 }
79 };
80}
81
82tuple_diff!();
83tuple_diff!(A0, A1, 0);
84tuple_diff!(A0, A1, 0, B0, B1, 1);
85tuple_diff!(A0, A1, 0, B0, B1, 1, C0, C1, 2);
86tuple_diff!(A0, A1, 0, B0, B1, 1, C0, C1, 2, D0, D1, 3);
87tuple_diff!(A0, A1, 0, B0, B1, 1, C0, C1, 2, D0, D1, 3, E0, E1, 4);
88tuple_diff!(A0, A1, 0, B0, B1, 1, C0, C1, 2, D0, D1, 3, E0, E1, 4, F0, F1, 5);
89tuple_diff!(A0, A1, 0, B0, B1, 1, C0, C1, 2, D0, D1, 3, E0, E1, 4, F0, F1, 5, G0, G1, 6);
90tuple_diff!(A0, A1, 0, B0, B1, 1, C0, C1, 2, D0, D1, 3, E0, E1, 4, F0, F1, 5, G0, G1, 6, H0, H1, 7);