pub trait Diffable {
type Diff;
fn diff(self: &Self, other: &Self) -> Self::Diff;
fn patch(self: &mut Self, diff: Self::Diff);
}
trait Reversible: Diffable {
type ReversibleDiff;
fn reversible_diff(self: &Self, other: &Self) -> Self::ReversibleDiff;
fn as_diff(diff: Self::ReversibleDiff) -> Self::Diff;
fn revert(self: &mut Self, diff: Self::ReversibleDiff);
}
impl Diffable for i32 {
type Diff = i32;
fn diff(self: &i32, other: &i32) -> i32 {
*other
}
fn patch(self: &mut i32, other: i32) {
*self = other;
}
}
impl<A, B> Diffable for (A, B)
where
A: Diffable,
B: Diffable,
{
type Diff = (A::Diff, B::Diff);
fn diff(self: &(A, B), other: &(A, B)) -> (A::Diff, B::Diff) {
(self.0.diff(&other.0), self.1.diff(&other.1))
}
fn patch(self: &mut (A, B), patch: (A::Diff, B::Diff)) {
self.0.patch(patch.0);
self.1.patch(patch.1);
}
}
pub enum EditScript<A, D> {
Add(usize, A),
Remove(usize, A),
Diff(usize, D),
}
impl<A: Diffable> Diffable for Vec<A> {
type Diff = Vec<EditScript<A, A::Diff>>;
fn diff(self: &Vec<A>, other: &Vec<A>) -> Vec<EditScript<A, A::Diff>> {
todo!()
}
fn patch(self: &mut Self, diff: Self::Diff) {
for operation in diff {
todo!()
}
}
}