diff/
lib.rs

1mod impls;
2#[cfg(test)]
3mod tests;
4pub mod utils;
5
6pub use diff_derive::Diff;
7pub use impls::*;
8
9/// A trait to diff and apply diffs between two structs
10/// The derive macro can be used on structs when all fields of the struct implement Diff
11/// Implementations are provided for bools, numeric types, Option types, and HashMaps
12pub trait Diff: Sized {
13    /// The type associated with the structs' difference
14    type Repr;
15
16    /// Produces a diff between two structs
17    fn diff(&self, other: &Self) -> Self::Repr;
18
19    /// Produces a diff between two structs, using an external diffing implementation
20    fn diff_custom<D: Differ<Self>>(&self, other: &Self, visitor: &D) -> D::Repr {
21        visitor.diff(self, other)
22    }
23
24    /// Applies the diff directly to the struct
25    fn apply(&mut self, diff: &Self::Repr);
26
27    /// Applies the diff directly to the struct, using an external diffing implementation
28    fn apply_custom<D: Differ<Self>>(&mut self, diff: &D::Repr, visitor: &D) {
29        visitor.apply(self, diff)
30    }
31
32    /// Applies the diff to the struct and produces a new struct
33    fn apply_new(&self, diff: &Self::Repr) -> Self {
34        let mut new = Self::identity();
35        new.apply(&new.diff(self));
36        new.apply(diff);
37        new
38    }
39
40    /// Applies the diff to the struct and produces a new struct, using an external diffing implementation
41    fn apply_new_custom<D: Differ<Self>>(&self, diff: &D::Repr, visitor: &D) -> Self {
42        let mut new = Self::identity();
43        new.apply_custom(&new.diff_custom(self, visitor), visitor);
44        new.apply_custom(diff, visitor);
45        new
46    }
47
48    /// The identity element of the struct
49    /// ```
50    /// use diff::Diff;
51    /// let s = 42;
52    /// let i = <i32 as Diff>::identity();
53    /// assert_eq!(i.apply_new(&i.diff(&s)), s);
54    /// ```
55    /// or mathematically speaking, `i + (s - i) = s`
56    fn identity() -> Self;
57}
58
59/// A trait allowing a custom struct to handle the diffing implementation for a type
60pub trait Differ<T> {
61    type Repr;
62
63    fn diff(&self, a: &T, b: &T) -> Self::Repr;
64
65    fn apply(&self, a: &mut T, b: &Self::Repr);
66}