Skip to main content

froodi/utils/
merge.rs

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}