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
/// A trait applies to types that support deep merging.
///
/// `a.merge_from(b)` behaves in the following ways:
///
/// ## `struct`s
///
/// Structs are merged by individually merging each of their fields. For example, given:
///
/// ```rust,ignore
/// struct S {
///     a: i32,
///     b: String,
/// }
/// ```
///
/// ... the expected impl of `DeepMerge` for `S` would be:
///
/// ```rust,ignore
/// impl DeepMerge for S {
///     fn merge_from(&mut self, other: Self) {
///         self.a.merge_from(other.a);
///         self.b.merge_from(other.b);
///     }
/// }
/// ```
///
/// The structs in the `k8s-openapi` crate behave this way. If you are implementing this trait for your own types, it is recommended to impl it in the same way.
///
/// ## `Option`
///
/// - If `b` is a `None`, `a` is unchanged.
///
/// - If `b` is a `Some(b_inner)`:
///
///   - If `a` is a `Some(a_inner)`, `a_inner` is merged with `b_inner`.
///
///   - If `a` is a `None`, `a` becomes `Some(b_inner)`.
///
/// ## `Vec`
///
/// The elements of `b` are appended to `a`.
///
/// ## `BTreeMap`
///
/// For each key `k` in `b`:
///
/// - If `a` contains the key `k` too, the value in `a` is merged with the value in `b`.
///
/// - If `a` does not contain the key `k`, the value in `b` is inserted into `a`.
///
/// ## `serde_json::Value`
///
/// `serde_json::Value` is merged using the JSON merge algorithm (RFC 7396).
///
/// ## Other types
///
/// `self` is just replaced by `other`.
pub trait DeepMerge {
	/// Merge `other` into `self`.
	fn merge_from(&mut self, other: Self);
}

macro_rules! default_overwriting_impl {
	() => {
		fn merge_from(&mut self, other: Self) {
			*self = other;
		}
	};
}

impl DeepMerge for bool { default_overwriting_impl! {} }
impl DeepMerge for i32 { default_overwriting_impl! {} }
impl DeepMerge for i64 { default_overwriting_impl! {} }
impl DeepMerge for f64 { default_overwriting_impl! {} }
impl DeepMerge for String { default_overwriting_impl! {} }
impl DeepMerge for crate::ByteString { default_overwriting_impl! {} }
impl<Tz> DeepMerge for chrono::DateTime<Tz> where Tz: chrono::TimeZone { default_overwriting_impl! {} }

impl DeepMerge for serde_json::Value {
	fn merge_from(&mut self, other: Self) {
		if let serde_json::Value::Object(this) = self {
			if let serde_json::Value::Object(other) = other {
				for (k, v) in other {
					if v.is_null() {
						this.remove(&k);
					}
					else {
						this.entry(k).or_insert(serde_json::Value::Null).merge_from(v);
					}
				}

				return;
			}
		}

		*self = other;
	}
}

impl<T> DeepMerge for Box<T> where T: DeepMerge {
	fn merge_from(&mut self, other: Self) {
		(**self).merge_from(*other);
	}
}

impl<K, V> DeepMerge for std::collections::BTreeMap<K, V> where K: Ord, V: DeepMerge {
	fn merge_from(&mut self, other: Self) {
		for (k, v) in other {
			match self.entry(k) {
				std::collections::btree_map::Entry::Vacant(e) => { e.insert(v); },
				std::collections::btree_map::Entry::Occupied(e) => e.into_mut().merge_from(v),
			}
		}
	}
}

impl<T> DeepMerge for Option<T> where T: DeepMerge {
	fn merge_from(&mut self, other: Self) {
		if let Some(other) = other {
			if let Some(s) = self {
				s.merge_from(other);
			} else {
				*self = Some(other);
			}
		}
	}
}

impl<T> DeepMerge for Vec<T> {
	fn merge_from(&mut self, other: Self) {
		self.extend(other);
	}
}