1use super::{IdPath, IdPathBuf};
2
3pub trait Diff: Sized {
5 fn record_diff<'a>(&'a self, old: &'a Self, id_path: &IdPath, difference: &mut Difference<&'a Self>);
8
9 fn diff<'a>(&'a self, old: &'a Self) -> Difference<&'a Self> {
11 let mut difference = Difference::new();
12 self.record_diff(old, IdPath::root(), &mut difference);
13 return difference;
14 }
15}
16
17#[derive(Debug, PartialEq, Eq, Clone)]
19pub struct Difference<T> {
20 pub removed: Vec<(IdPathBuf, T)>,
21 pub changed: Vec<(IdPathBuf, T, T)>,
22 pub added: Vec<(IdPathBuf, T)>,
23}
24
25impl<T> Difference<T> {
26 pub fn new() -> Self {
27 Self {
28 removed: Vec::new(),
29 changed: Vec::new(),
30 added: Vec::new(),
31 }
32 }
33
34 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Difference<U> {
35 Difference {
36 removed: self.removed.into_iter().map(|(p, x)| (p, f(x))).collect(),
37 changed: self.changed.into_iter().map(|(p, x, y)| (p, f(x), f(y))).collect(),
38 added: self.added.into_iter().map(|(p, x)| (p, f(x))).collect(),
39 }
40 }
41}
42
43impl<T> Default for Difference<T> {
44 fn default() -> Self {
45 Self::new()
46 }
47}