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}