1use crate::Profile;
2use crate::value::{Value, Map};
3
4#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum Order {
6 Merge,
7 Join,
8 Adjoin,
9 Admerge,
10}
11
12pub trait Coalescible: Sized {
13 fn coalesce(self, other: Self, order: Order) -> Self;
14 fn merge(self, other: Self) -> Self { self.coalesce(other, Order::Merge) }
15}
16
17impl Coalescible for Profile {
18 fn coalesce(self, other: Self, order: Order) -> Self {
19 match order {
20 Order::Join | Order::Adjoin => self,
21 Order::Merge | Order::Admerge => other,
22 }
23 }
24}
25
26impl Coalescible for Value {
27 fn coalesce(self, other: Self, o: Order) -> Self {
28 use {Value::Dict as D, Value::Array as A, Order::*};
29 match (self, other, o) {
30 (D(t, a), D(_, b), Join | Adjoin) | (D(_, a), D(t, b), Merge | Admerge) => D(t, a.coalesce(b, o)),
31 (A(t, mut a), A(_, b), Adjoin | Admerge) => A(t, { a.extend(b); a }),
32 (v, _, Join | Adjoin) | (_, v, Merge | Admerge) => v,
33 }
34 }
35}
36
37impl<K: Eq + std::hash::Hash + Ord, V: Coalescible> Coalescible for Map<K, V> {
38 fn coalesce(self, mut other: Self, order: Order) -> Self {
39 let mut joined = Map::new();
40 for (a_key, a_val) in self {
41 match other.remove(&a_key) {
42 Some(b_val) => joined.insert(a_key, a_val.coalesce(b_val, order)),
43 None => joined.insert(a_key, a_val),
44 };
45 }
46
47 joined.extend(other);
49 joined
50 }
51}