1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
use crate::traitdef::{Delegate, Mutable};
use std::{borrow::BorrowMut, borrow::Cow, fmt::Display, marker::PhantomData};

/// A `Delegate` which applies differences to a target object.
///
/// It wraps the target object and applies all calls by the `diff`
/// algorithm to it, which changes it in some way.
///
/// Custom resolver functions can be provided to arbitrarily alter
/// the way the merge is performed. This allows you, for example, to
/// keep your own meta-data, or to implement custom conflict resolutions.
///
/// # Examples
/// Please see the [tests][tests] for usage examples.
///
/// [tests]: https://github.com/Byron/treediff-rs/blob/master/tests/merge.rs#L22
pub struct Merger<K, V, BF, F> {
    cursor: Vec<K>,
    inner: V,
    filter: BF,
    _d: PhantomData<F>,
}

fn appended<K>(keys: &[K], k: Option<&K>) -> Vec<K>
where
    K: Clone,
{
    let mut keys = Vec::from(keys);
    if let Some(k) = k {
        keys.push(k.clone());
    }
    keys
}

/// A filter to manipulate calls to be made to `Value`s implementing the `Mutable` trait in calls
/// made by the `Merger` `Delegate`.
///
/// This allows you to control the exact way merge operations are performed independently of the
/// type implementing the `Value` trait, which usually is not under your control.
pub trait MutableFilter {
    /// Called during `Delegate::modified(...)`, returns `None` to cause the Value at the `keys` to
    /// be removed, or any Value to be set in its place.
    ///
    /// `old` is the previous value at the given `keys` path, and `new` is the one now at its place.
    /// `_target` provides access to the target of the merge operation.
    fn resolve_conflict<'a, K: Clone + Display, V: Clone>(
        &mut self,
        _keys: &[K],
        _old: &'a V,
        new: &'a V,
        _target: &mut V,
    ) -> Option<Cow<'a, V>> {
        Some(Cow::Borrowed(new))
    }
    /// Called during `Delegate::removed(...)`, returns `None` to allow the Value at the `keys` path
    /// to be removed, or any Value to be set in its place instead.
    ///
    /// `removed` is the Value which is to be removed.
    /// `_target` provides access to the target of the merge operation.
    fn resolve_removal<'a, K: Clone + Display, V: Clone>(
        &mut self,
        _keys: &[K],
        _removed: &'a V,
        _target: &mut V,
    ) -> Option<Cow<'a, V>> {
        None
    }
}

/// The default implementation used when when creating a new `Merger` from any `Value` type.
///
/// If you want to choose your own filter, use `Merger::with_filter(...)` instead.
pub struct DefaultMutableFilter;
impl MutableFilter for DefaultMutableFilter {}

impl<'a, K, V, F, BF> Delegate<'a, K, V> for Merger<K, V, BF, F>
where
    V: Mutable<Key = K, Item = V> + Clone + 'a,
    K: Clone + Display,
    F: MutableFilter,
    BF: BorrowMut<F>,
{
    fn push(&mut self, k: &K) {
        self.cursor.push(k.clone());
    }
    fn pop(&mut self) {
        self.cursor.pop();
    }
    fn removed<'b>(&mut self, k: &'b K, v: &'a V) {
        let keys = appended(&self.cursor, Some(k));
        match self
            .filter
            .borrow_mut()
            .resolve_removal(&keys, v, &mut self.inner)
        {
            Some(nv) => self.inner.set(&keys, &nv),
            None => self.inner.remove(&keys),
        }
    }
    fn added<'b>(&mut self, k: &'b K, v: &'a V) {
        self.inner.set(&appended(&self.cursor, Some(k)), v);
    }
    fn unchanged<'b>(&mut self, v: &'a V) {
        self.inner.set(&self.cursor, v)
    }
    fn modified<'b>(&mut self, old: &'a V, new: &'a V) {
        let keys = appended(&self.cursor, None);
        match self
            .filter
            .borrow_mut()
            .resolve_conflict(&keys, old, new, &mut self.inner)
        {
            Some(v) => self.inner.set(&keys, &v),
            None => self.inner.remove(&keys),
        }
    }
}

impl<K, V, BF, F> Merger<K, V, BF, F> {
    /// Consume the merger and return the contained target Value, which is the result of the
    /// merge operation.
    pub fn into_inner(self) -> V {
        self.inner
    }

    /// Returns a mutable borrow to the `MutableFilter` instance
    pub fn filter_mut(&mut self) -> &mut BF {
        &mut self.filter
    }

    /// Returns a borrow to the `MutableFilter` instance
    pub fn filter(&self) -> &BF {
        &self.filter
    }
}

impl<K, V, BF, F> AsRef<V> for Merger<K, V, BF, F> {
    fn as_ref(&self) -> &V {
        &self.inner
    }
}

impl<'a, V, BF, F> Merger<V::Key, V, BF, F>
where
    V: Mutable + 'a + Clone,
    F: MutableFilter,
    BF: BorrowMut<F>,
{
    /// Return a new Merger with the given initial value `v` and the filter `f`
    pub fn with_filter(v: V, f: BF) -> Self {
        Merger {
            inner: v,
            cursor: Vec::new(),
            filter: f,
            _d: PhantomData,
        }
    }
}

impl<'a, V> From<V> for Merger<V::Key, V, DefaultMutableFilter, DefaultMutableFilter>
where
    V: Mutable + 'a + Clone,
{
    /// Return a new merger with the given initial value `v`, and the `DefaultMutableFilter`.
    fn from(v: V) -> Self {
        Merger {
            inner: v,
            cursor: Vec::new(),
            filter: DefaultMutableFilter,
            _d: PhantomData,
        }
    }
}