1use crate::{any::TypeInfo, macros_utils::types::RegistryOrEntry, registry::InstantiatorData, utils::hlist, Registry};
2
3pub trait Merge<T> {
4 type Output;
5
6 #[must_use]
7 fn merge(self, other: T) -> Self::Output;
8}
9
10impl Merge<Registry> for Registry {
11 type Output = Registry;
12
13 #[inline]
14 fn merge(mut self, other: Registry) -> Self::Output {
15 self.entries.extend(other.entries);
16 self
17 }
18}
19
20impl Merge<(TypeInfo, InstantiatorData)> for Registry {
21 type Output = Registry;
22
23 #[inline]
24 fn merge(mut self, (key, value): (TypeInfo, InstantiatorData)) -> Self::Output {
25 self.entries.insert(key, value);
26 self
27 }
28}
29
30impl Merge<RegistryOrEntry> for Registry {
31 type Output = Self;
32
33 #[inline]
34 fn merge(self, registry_or_entry: RegistryOrEntry) -> Self::Output {
35 match registry_or_entry {
36 RegistryOrEntry::Registry(registry) => self.merge(registry),
37 RegistryOrEntry::Entry(entry) => self.merge(entry),
38 }
39 }
40}
41
42impl<H> Merge<H> for Registry
43where
44 H: hlist::IntoIterator<RegistryOrEntry>,
45{
46 type Output = Self;
47
48 #[inline]
49 fn merge(self, other: H) -> Self::Output {
50 other.into_iter().fold(self, Merge::merge)
51 }
52}
53
54#[cfg(feature = "async")]
55mod async_impl {
56 use super::{hlist, Merge, Registry, TypeInfo};
57 use crate::{
58 async_impl::{self, RegistryWithSync},
59 macros_utils::types::{
60 RegistryKind::{self, Async, AsyncWithSync, Sync},
61 RegistryKindOrEntry::{self, Entry, Kind},
62 },
63 };
64
65 impl Merge<async_impl::Registry> for async_impl::Registry {
66 type Output = Self;
67
68 #[inline]
69 fn merge(mut self, registry: Self) -> Self::Output {
70 self.entries.extend(registry.entries);
71 self
72 }
73 }
74
75 impl Merge<Registry> for async_impl::Registry {
76 type Output = RegistryWithSync;
77
78 #[inline]
79 fn merge(self, sync: Registry) -> Self::Output {
80 Self::Output { registry: self, sync }
81 }
82 }
83
84 impl Merge<async_impl::Registry> for Registry {
85 type Output = RegistryWithSync;
86
87 #[inline]
88 fn merge(self, registry: async_impl::Registry) -> Self::Output {
89 Self::Output { registry, sync: self }
90 }
91 }
92
93 impl Merge<RegistryWithSync> for RegistryWithSync {
94 type Output = Self;
95
96 #[inline]
97 fn merge(mut self, registry: RegistryWithSync) -> Self::Output {
98 self.sync.entries.extend(registry.sync.entries);
99 self.registry.entries.extend(registry.registry.entries);
100 self
101 }
102 }
103
104 impl Merge<Registry> for RegistryWithSync {
105 type Output = Self;
106
107 #[inline]
108 fn merge(mut self, registry: Registry) -> Self::Output {
109 self.sync.entries.extend(registry.entries);
110 self
111 }
112 }
113
114 impl Merge<async_impl::Registry> for RegistryWithSync {
115 type Output = Self;
116
117 #[inline]
118 fn merge(mut self, registry: async_impl::Registry) -> Self::Output {
119 self.registry.entries.extend(registry.entries);
120 self
121 }
122 }
123
124 impl Merge<(TypeInfo, async_impl::InstantiatorData)> for Registry {
125 type Output = RegistryWithSync;
126
127 #[inline]
128 fn merge(self, (key, value): (TypeInfo, async_impl::InstantiatorData)) -> Self::Output {
129 let mut registry = async_impl::Registry::default();
130 registry.entries.insert(key, value);
131 Self::Output { registry, sync: self }
132 }
133 }
134
135 impl Merge<(TypeInfo, async_impl::InstantiatorData)> for async_impl::Registry {
136 type Output = Self;
137
138 #[inline]
139 fn merge(mut self, (key, value): (TypeInfo, async_impl::InstantiatorData)) -> Self::Output {
140 self.entries.insert(key, value);
141 self
142 }
143 }
144
145 impl Merge<(TypeInfo, async_impl::InstantiatorData)> for RegistryWithSync {
146 type Output = Self;
147
148 #[inline]
149 fn merge(mut self, (key, value): (TypeInfo, async_impl::InstantiatorData)) -> Self::Output {
150 self.registry.entries.insert(key, value);
151 self
152 }
153 }
154
155 impl Merge<Registry> for RegistryKind {
156 type Output = Self;
157
158 #[inline]
159 fn merge(self, registry: Registry) -> Self::Output {
160 match self {
161 Sync(other) => Sync(registry.merge(other)),
162 Async(other) => AsyncWithSync(registry.merge(other)),
163 AsyncWithSync(other) => AsyncWithSync(other.merge(registry)),
164 }
165 }
166 }
167
168 impl Merge<async_impl::Registry> for RegistryKind {
169 type Output = Self;
170
171 #[inline]
172 fn merge(self, registry: async_impl::Registry) -> Self::Output {
173 match self {
174 Sync(other) => AsyncWithSync(other.merge(registry)),
175 Async(other) => Async(registry.merge(other)),
176 AsyncWithSync(other) => AsyncWithSync(other.merge(registry)),
177 }
178 }
179 }
180
181 impl Merge<RegistryWithSync> for RegistryKind {
182 type Output = Self;
183
184 #[inline]
185 fn merge(self, registry: RegistryWithSync) -> Self::Output {
186 match self {
187 Sync(other) => AsyncWithSync(registry.merge(other)),
188 Async(other) => AsyncWithSync(registry.merge(other)),
189 AsyncWithSync(other) => AsyncWithSync(registry.merge(other)),
190 }
191 }
192 }
193
194 impl Merge<RegistryKindOrEntry> for RegistryWithSync {
195 type Output = Self;
196
197 #[inline]
198 fn merge(self, registry_kind_or_entry: RegistryKindOrEntry) -> Self::Output {
199 match registry_kind_or_entry {
200 Kind(Sync(registry)) => self.merge(registry),
201 Kind(Async(registry)) => self.merge(registry),
202 Kind(AsyncWithSync(registry)) => self.merge(registry),
203 Entry(entry) => self.merge(entry),
204 }
205 }
206 }
207
208 impl Merge<RegistryKindOrEntry> for async_impl::Registry {
209 type Output = RegistryWithSync;
210
211 #[inline]
212 fn merge(self, registry_kind_or_entry: RegistryKindOrEntry) -> Self::Output {
213 match registry_kind_or_entry {
214 Kind(Sync(registry)) => self.merge(registry),
215 Kind(Async(registry)) => self.merge(registry).into(),
216 Kind(AsyncWithSync(registry)) => registry.merge(self),
217 Entry(entry) => self.merge(entry).into(),
218 }
219 }
220 }
221
222 impl Merge<RegistryKindOrEntry> for RegistryKind {
223 type Output = Self;
224
225 #[inline]
226 fn merge(self, registry_kind_or_entry: RegistryKindOrEntry) -> Self::Output {
227 match (self, registry_kind_or_entry) {
228 (Sync(registry), Kind(Sync(other))) => Sync(registry.merge(other)),
229 (Async(registry), Kind(Async(other))) => Async(registry.merge(other)),
230 (AsyncWithSync(registry), Kind(AsyncWithSync(other))) => AsyncWithSync(registry.merge(other)),
231 (Sync(registry), Entry(entry)) => AsyncWithSync(registry.merge(entry)),
232 (Async(registry), Entry(entry)) => Async(registry.merge(entry)),
233 (AsyncWithSync(registry), Entry(entry)) => AsyncWithSync(registry.merge(entry)),
234 (Sync(registry), Kind(AsyncWithSync(other))) => AsyncWithSync(other.merge(registry)),
235 (Async(registry), Kind(Sync(other))) => AsyncWithSync(other.merge(registry)),
236 (AsyncWithSync(registry), Kind(Sync(other))) => AsyncWithSync(registry.merge(other)),
237 (Sync(registry), Kind(Async(other))) => AsyncWithSync(registry.merge(other)),
238 (Async(registry), Kind(AsyncWithSync(other))) => AsyncWithSync(other.merge(registry)),
239 (AsyncWithSync(registry), Kind(Async(other))) => AsyncWithSync(registry.merge(other)),
240 }
241 }
242 }
243
244 impl<H> Merge<H> for RegistryWithSync
245 where
246 H: hlist::IntoIterator<RegistryKindOrEntry>,
247 {
248 type Output = Self;
249
250 fn merge(self, other: H) -> Self::Output {
251 other.into_iter().fold(self, Merge::merge)
252 }
253 }
254}