Skip to main content

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
77                    let merged = a.merge(b).map_err(|mut e| {
78                        e.field.push_front(&format!("\"{k}\""));
79                        e
80                    })?;
81
82                    self.insert(k, merged);
83                }
84            }
85        }
86
87        Ok(())
88    }
89}
90
91impl<T> Merge for BTreeSet<T>
92where
93    T: Ord,
94{
95    fn merge_ref(&mut self, mut other: Self) -> Result<(), Error> {
96        self.append(&mut other);
97        Ok(())
98    }
99}
100
101#[cfg(test)]
102#[allow(clippy::unwrap_used)]
103mod tests {
104    use super::*;
105    use crate::test::*;
106
107    #[test]
108    fn test_box() {
109        let a = Box::new(Merged(false));
110        let b = Box::new(Merged(false));
111
112        let c = a.merge(b).unwrap();
113        assert!((*c).0);
114    }
115
116    #[test]
117    fn test_vec() {
118        use alloc::vec;
119
120        let a = vec![1, 2, 5, 7, 0];
121        let b = vec![2, 8, 9, 10];
122
123        let c = a.merge(b).unwrap();
124        assert_eq!(c, &[1, 2, 5, 7, 0, 2, 8, 9, 10]);
125    }
126
127    #[test]
128    fn test_linked_list() {
129        let a: LinkedList<i32> = [1, 2, 5, 7, 0].into_iter().collect();
130        let b: LinkedList<i32> = [2, 8, 9, 10].into_iter().collect();
131
132        let c = a.merge(b).unwrap();
133        assert!(c.iter().eq(&[1, 2, 5, 7, 0, 2, 8, 9, 10]));
134    }
135
136    #[test]
137    fn test_btree_map() {
138        fn from_keys(keys: &[&'static str]) -> BTreeMap<&'static str, Merged> {
139            keys.iter()
140                .copied()
141                .map(|k| (k, Merged::default()))
142                .collect()
143        }
144
145        let a = from_keys(&["key1", "key2", "key3", "key4", "key7"]);
146        let b = from_keys(&["key5", "key1", "key7", "key2", "key6"]);
147
148        let c = a.merge(b).unwrap();
149
150        let expected = [
151            ("key1", Merged(true)),
152            ("key2", Merged(true)),
153            ("key3", Merged(false)),
154            ("key4", Merged(false)),
155            ("key5", Merged(false)),
156            ("key6", Merged(false)),
157            ("key7", Merged(true)),
158        ];
159
160        assert_eq!(expected.len(), c.len());
161
162        for (k, v) in expected {
163            assert_eq!(c[k].0, v.0, "key: {k}");
164        }
165    }
166
167    #[test]
168    fn test_btree_set() {
169        let a: BTreeSet<i32> = [1, 2, 5, 7, 0, 10].into_iter().collect();
170        let b: BTreeSet<i32> = [2, 8, 9, 10, 5].into_iter().collect();
171
172        let mut c: Vec<i32> = a.merge(b).unwrap().into_iter().collect();
173        c.sort_unstable();
174        assert_eq!(c, &[0, 1, 2, 5, 7, 8, 9, 10]);
175    }
176}