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}