alpm_srcinfo/source_info/v1/
merged.rs1use alpm_types::{
3 Architecture,
4 Architectures,
5 FullVersion,
6 License,
7 MakepkgOption,
8 Name,
9 OpenPGPIdentifier,
10 OptionalDependency,
11 PackageDescription,
12 PackageRelation,
13 RelationOrSoname,
14 RelativeFilePath,
15 SkippableChecksum,
16 Source,
17 Url,
18 digests::{Blake2b512, Crc32Cksum, Md5, Sha1, Sha224, Sha256, Sha384, Sha512},
19};
20use serde::{Deserialize, Serialize};
21
22#[cfg(doc)]
23use crate::source_info::v1::package::Override;
24use crate::{
25 SourceInfoV1,
26 source_info::v1::{
27 package::Package,
28 package_base::{PackageBase, PackageBaseArchitecture},
29 },
30};
31
32#[derive(Clone, Debug, Deserialize, Serialize)]
38pub struct MergedPackage {
39 pub name: Name,
41 pub description: Option<PackageDescription>,
43 pub url: Option<Url>,
45 pub licenses: Vec<License>,
47 pub architecture: Architecture,
49 pub changelog: Option<RelativeFilePath>,
51
52 pub install: Option<RelativeFilePath>,
55 pub groups: Vec<String>,
57 pub options: Vec<MakepkgOption>,
59 pub backups: Vec<RelativeFilePath>,
61
62 pub version: FullVersion,
64 pub pgp_fingerprints: Vec<OpenPGPIdentifier>,
67
68 pub dependencies: Vec<RelationOrSoname>,
70 pub optional_dependencies: Vec<OptionalDependency>,
72 pub provides: Vec<RelationOrSoname>,
74 pub conflicts: Vec<PackageRelation>,
76 pub replaces: Vec<PackageRelation>,
78 pub check_dependencies: Vec<PackageRelation>,
80 pub make_dependencies: Vec<PackageRelation>,
82
83 pub sources: Vec<MergedSource>,
85 pub no_extracts: Vec<String>,
87}
88
89#[derive(Clone, Debug)]
91pub struct MergedPackagesIterator<'a> {
92 pub(crate) architecture: Architecture,
93 pub(crate) source_info: &'a SourceInfoV1,
94 pub(crate) package_iterator: std::slice::Iter<'a, Package>,
95}
96
97impl Iterator for MergedPackagesIterator<'_> {
98 type Item = MergedPackage;
99
100 fn next(&mut self) -> Option<MergedPackage> {
101 let package = self.package_iterator.find(|package| {
103 let architectures = match &package.architectures {
106 Some(value) => value,
107 None => &self.source_info.base.architectures,
108 };
109
110 match &self.architecture {
111 Architecture::Any => *architectures == Architectures::Any,
113 Architecture::Some(iterator_arch) => match architectures {
117 Architectures::Any => true,
118 Architectures::Some(arch_vec) => arch_vec.contains(iterator_arch),
119 },
120 }
121 })?;
122
123 Some(MergedPackage::from_base_and_package(
124 self.architecture.clone(),
125 &self.source_info.base,
126 package,
127 ))
128 }
129}
130
131#[derive(Clone, Debug, Deserialize, Serialize)]
136pub struct MergedSource {
137 pub source: Source,
139 pub b2_checksum: Option<SkippableChecksum<Blake2b512>>,
141 pub md5_checksum: Option<SkippableChecksum<Md5>>,
143 pub sha1_checksum: Option<SkippableChecksum<Sha1>>,
145 pub sha224_checksum: Option<SkippableChecksum<Sha224>>,
147 pub sha256_checksum: Option<SkippableChecksum<Sha256>>,
149 pub sha384_checksum: Option<SkippableChecksum<Sha384>>,
151 pub sha512_checksum: Option<SkippableChecksum<Sha512>>,
153 pub crc_checksum: Option<SkippableChecksum<Crc32Cksum>>,
155}
156
157#[derive(Clone, Debug)]
163pub struct MergedSourceIterator<'a> {
164 sources: std::slice::Iter<'a, Source>,
165 b2_checksums: std::slice::Iter<'a, SkippableChecksum<Blake2b512>>,
166 md5_checksums: std::slice::Iter<'a, SkippableChecksum<Md5>>,
167 sha1_checksums: std::slice::Iter<'a, SkippableChecksum<Sha1>>,
168 sha224_checksums: std::slice::Iter<'a, SkippableChecksum<Sha224>>,
169 sha256_checksums: std::slice::Iter<'a, SkippableChecksum<Sha256>>,
170 sha384_checksums: std::slice::Iter<'a, SkippableChecksum<Sha384>>,
171 sha512_checksums: std::slice::Iter<'a, SkippableChecksum<Sha512>>,
172 crc_checksums: std::slice::Iter<'a, SkippableChecksum<Crc32Cksum>>,
173}
174
175impl Iterator for MergedSourceIterator<'_> {
176 type Item = MergedSource;
177
178 fn next(&mut self) -> Option<MergedSource> {
179 let source = self.sources.next()?;
180
181 Some(MergedSource {
182 source: source.clone(),
183 b2_checksum: self.b2_checksums.next().cloned(),
184 md5_checksum: self.md5_checksums.next().cloned(),
185 sha1_checksum: self.sha1_checksums.next().cloned(),
186 sha224_checksum: self.sha224_checksums.next().cloned(),
187 sha256_checksum: self.sha256_checksums.next().cloned(),
188 sha384_checksum: self.sha384_checksums.next().cloned(),
189 sha512_checksum: self.sha512_checksums.next().cloned(),
190 crc_checksum: self.crc_checksums.next().cloned(),
191 })
192 }
193}
194
195impl MergedPackage {
196 pub fn from_base_and_package<A: Into<Architecture>>(
213 architecture: A,
214 base: &PackageBase,
215 package: &Package,
216 ) -> MergedPackage {
217 let name = package.name.clone();
218 let architecture = &architecture.into();
219
220 let mut merged_package = Self::from_base(architecture.clone(), name, base);
222
223 merged_package.merge_package(package);
225
226 let mut architecture_properties = if let Architecture::Some(system_arch) = &architecture
230 && let Some(properties) = base.architecture_properties.get(system_arch)
231 {
232 properties.clone()
233 } else {
234 PackageBaseArchitecture::default()
235 };
236
237 if let Architecture::Some(system_arch) = architecture
239 && let Some(package_properties) = package.architecture_properties.get(system_arch)
240 {
241 architecture_properties.merge_package_properties(package_properties.clone());
242 }
243
244 merged_package.merge_architecture_properties(&architecture_properties);
246
247 merged_package
248 }
249
250 pub fn from_base<A: Into<Architecture>>(
263 architecture: A,
264 name: Name,
265 base: &PackageBase,
266 ) -> MergedPackage {
267 let merged_sources = MergedSourceIterator {
269 sources: base.sources.iter(),
270 b2_checksums: base.b2_checksums.iter(),
271 md5_checksums: base.md5_checksums.iter(),
272 sha1_checksums: base.sha1_checksums.iter(),
273 sha224_checksums: base.sha224_checksums.iter(),
274 sha256_checksums: base.sha256_checksums.iter(),
275 sha384_checksums: base.sha384_checksums.iter(),
276 sha512_checksums: base.sha512_checksums.iter(),
277 crc_checksums: base.crc_checksums.iter(),
278 };
279
280 let architecture = match &base.architectures {
284 Architectures::Any => &Architecture::Any,
285 Architectures::Some(_) => &architecture.into(),
286 };
287
288 MergedPackage {
289 name,
290 description: base.description.clone(),
291 url: base.url.clone(),
292 licenses: base.licenses.clone(),
293 architecture: architecture.clone(),
294 changelog: base.changelog.clone(),
295 install: base.install.clone(),
296 groups: base.groups.clone(),
297 options: base.options.clone(),
298 backups: base.backups.clone(),
299 version: base.version.clone(),
300 pgp_fingerprints: base.pgp_fingerprints.clone(),
301 dependencies: base.dependencies.clone(),
302 optional_dependencies: base.optional_dependencies.clone(),
303 provides: base.provides.clone(),
304 conflicts: base.conflicts.clone(),
305 replaces: base.replaces.clone(),
306 check_dependencies: base.check_dependencies.clone(),
307 make_dependencies: base.make_dependencies.clone(),
308 sources: merged_sources.collect(),
309 no_extracts: base.no_extracts.clone(),
310 }
311 }
312
313 fn merge_package(&mut self, package: &Package) {
317 let package = package.clone();
318
319 if let Some(value) = package.architectures {
323 if matches!(value, Architectures::Any) {
324 self.architecture = Architecture::Any
325 }
326 };
327
328 package.description.merge_option(&mut self.description);
329 package.url.merge_option(&mut self.url);
330 package.changelog.merge_option(&mut self.changelog);
331 package.licenses.merge_vec(&mut self.licenses);
332 package.install.merge_option(&mut self.install);
333 package.groups.merge_vec(&mut self.groups);
334 package.options.merge_vec(&mut self.options);
335 package.backups.merge_vec(&mut self.backups);
336 package.dependencies.merge_vec(&mut self.dependencies);
337 package
338 .optional_dependencies
339 .merge_vec(&mut self.optional_dependencies);
340 package.provides.merge_vec(&mut self.provides);
341 package.conflicts.merge_vec(&mut self.conflicts);
342 package.replaces.merge_vec(&mut self.replaces);
343 }
344
345 fn merge_architecture_properties(&mut self, base_architecture: &PackageBaseArchitecture) {
351 let merged_sources = MergedSourceIterator {
353 sources: base_architecture.sources.iter(),
354 b2_checksums: base_architecture.b2_checksums.iter(),
355 md5_checksums: base_architecture.md5_checksums.iter(),
356 sha1_checksums: base_architecture.sha1_checksums.iter(),
357 sha224_checksums: base_architecture.sha224_checksums.iter(),
358 sha256_checksums: base_architecture.sha256_checksums.iter(),
359 sha384_checksums: base_architecture.sha384_checksums.iter(),
360 sha512_checksums: base_architecture.sha512_checksums.iter(),
361 crc_checksums: base_architecture.crc_checksums.iter(),
362 };
363
364 self.dependencies
365 .extend_from_slice(&base_architecture.dependencies);
366 self.optional_dependencies
367 .extend_from_slice(&base_architecture.optional_dependencies);
368 self.provides.extend_from_slice(&base_architecture.provides);
369 self.conflicts
370 .extend_from_slice(&base_architecture.conflicts);
371 self.replaces.extend_from_slice(&base_architecture.replaces);
372 self.check_dependencies
373 .extend_from_slice(&base_architecture.check_dependencies);
374 self.make_dependencies
375 .extend_from_slice(&base_architecture.make_dependencies);
376
377 self.sources
378 .extend_from_slice(&merged_sources.collect::<Vec<MergedSource>>());
379 }
380}