module/merge/impls/
alloc.rs

1use core::cmp::Ord;
2use core::fmt::Display;
3
4use alloc::boxed::Box;
5use alloc::collections::{BTreeMap, BTreeSet, LinkedList};
6use alloc::vec::Vec;
7
8use super::prelude::*;
9
10unmergeable! {
11    Box<core::ffi::CStr>, Box<str>,
12    alloc::ffi::CString,
13    alloc::string::String
14}
15
16impl<T> Merge for Box<[T]> {
17    unmergeable!();
18}
19
20impl<T> Merge for alloc::borrow::Cow<'_, T>
21where
22    T: ?Sized + alloc::borrow::ToOwned,
23    T::Owned: Merge,
24{
25    fn merge_ref(&mut self, other: Self) -> Result<(), Error> {
26        match self {
27            Self::Owned(x) => x.merge_ref(other.into_owned()),
28            Self::Borrowed(x) => {
29                let mut x = x.to_owned();
30                x.merge_ref(other.into_owned())?;
31                *self = Self::Owned(x);
32                Ok(())
33            }
34        }
35    }
36}
37
38impl<T> Merge for Box<T>
39where
40    T: Merge,
41{
42    fn merge_ref(&mut self, other: Self) -> Result<(), Error> {
43        T::merge_ref(self, *other)
44    }
45}
46
47impl<T> Merge for Vec<T> {
48    fn merge_ref(&mut self, mut other: Self) -> Result<(), Error> {
49        self.append(&mut other);
50        Ok(())
51    }
52}
53
54impl<T> Merge for LinkedList<T> {
55    fn merge_ref(&mut self, mut other: Self) -> Result<(), Error> {
56        self.append(&mut other);
57        Ok(())
58    }
59}
60
61impl<K, V> Merge for BTreeMap<K, V>
62where
63    K: Ord + Display,
64    V: Merge,
65{
66    fn merge_ref(&mut self, other: Self) -> Result<(), Error> {
67        use alloc::collections::btree_map::Entry;
68
69        for (k, b) in other {
70            match self.entry(k) {
71                Entry::Vacant(x) => {
72                    x.insert(b);
73                }
74                Entry::Occupied(x) => {
75                    let (k, a) = x.remove_entry();
76                    let merged = a.merge(b).with_value(|| format!("\"{k}\""))?;
77                    self.insert(k, merged);
78                }
79            }
80        }
81
82        Ok(())
83    }
84}
85
86impl<T> Merge for BTreeSet<T>
87where
88    T: Ord,
89{
90    fn merge_ref(&mut self, mut other: Self) -> Result<(), Error> {
91        self.append(&mut other);
92        Ok(())
93    }
94}
95
96#[cfg(test)]
97mod tests {
98    use super::*;
99    use crate::test::*;
100
101    #[test]
102    fn test_box() {
103        let a = Box::new(Merged(false));
104        let b = Box::new(Merged(false));
105
106        let c = a.merge(b).unwrap();
107        assert!((*c).0);
108    }
109
110    #[test]
111    fn test_vec() {
112        use alloc::vec;
113
114        let a = vec![1, 2, 5, 7, 0];
115        let b = vec![2, 8, 9, 10];
116
117        let c = a.merge(b).unwrap();
118        assert_eq!(c, &[1, 2, 5, 7, 0, 2, 8, 9, 10]);
119    }
120
121    #[test]
122    fn test_linked_list() {
123        let a: LinkedList<i32> = [1, 2, 5, 7, 0].into_iter().collect();
124        let b: LinkedList<i32> = [2, 8, 9, 10].into_iter().collect();
125
126        let c = a.merge(b).unwrap();
127        assert!(c.iter().eq(&[1, 2, 5, 7, 0, 2, 8, 9, 10]));
128    }
129
130    #[test]
131    fn test_btree_map() {
132        fn from_keys(keys: &[&'static str]) -> BTreeMap<&'static str, Merged> {
133            keys.iter()
134                .copied()
135                .map(|k| (k, Merged::default()))
136                .collect()
137        }
138
139        let a = from_keys(&["key1", "key2", "key3", "key4", "key7"]);
140        let b = from_keys(&["key5", "key1", "key7", "key2", "key6"]);
141
142        let c = a.merge(b).unwrap();
143
144        let expected = [
145            ("key1", Merged(true)),
146            ("key2", Merged(true)),
147            ("key3", Merged(false)),
148            ("key4", Merged(false)),
149            ("key5", Merged(false)),
150            ("key6", Merged(false)),
151            ("key7", Merged(true)),
152        ];
153
154        assert_eq!(expected.len(), c.len());
155
156        for (k, v) in expected {
157            assert_eq!(c[k].0, v.0, "key: {k}");
158        }
159    }
160
161    #[test]
162    fn test_btree_set() {
163        let a: BTreeSet<i32> = [1, 2, 5, 7, 0, 10].into_iter().collect();
164        let b: BTreeSet<i32> = [2, 8, 9, 10, 5].into_iter().collect();
165
166        let mut c: Vec<i32> = a.merge(b).unwrap().into_iter().collect();
167        c.sort_unstable();
168        assert_eq!(c, &[0, 1, 2, 5, 7, 8, 9, 10]);
169    }
170}