alpm_srcinfo/source_info/v1/
merged.rs1use alpm_types::{
3 Architecture,
4 FullVersion,
5 License,
6 MakepkgOption,
7 Name,
8 OpenPGPIdentifier,
9 OptionalDependency,
10 PackageDescription,
11 PackageRelation,
12 RelationOrSoname,
13 RelativePath,
14 SkippableChecksum,
15 Source,
16 Url,
17 digests::{Blake2b512, Md5, Sha1, Sha224, Sha256, Sha384, Sha512},
18};
19use serde::{Deserialize, Serialize};
20
21#[cfg(doc)]
22use crate::source_info::v1::package::Override;
23use crate::{
24 SourceInfoV1,
25 source_info::v1::{
26 package::Package,
27 package_base::{PackageBase, PackageBaseArchitecture},
28 },
29};
30
31#[derive(Clone, Debug, Deserialize, Serialize)]
37pub struct MergedPackage {
38 pub name: Name,
40 pub description: Option<PackageDescription>,
42 pub url: Option<Url>,
44 pub licenses: Vec<License>,
46 pub architecture: Architecture,
48 pub changelog: Option<RelativePath>,
50
51 pub install: Option<RelativePath>,
54 pub groups: Vec<String>,
56 pub options: Vec<MakepkgOption>,
58 pub backups: Vec<RelativePath>,
60
61 pub version: FullVersion,
63 pub pgp_fingerprints: Vec<OpenPGPIdentifier>,
66
67 pub dependencies: Vec<RelationOrSoname>,
69 pub optional_dependencies: Vec<OptionalDependency>,
71 pub provides: Vec<RelationOrSoname>,
73 pub conflicts: Vec<PackageRelation>,
75 pub replaces: Vec<PackageRelation>,
77 pub check_dependencies: Vec<PackageRelation>,
79 pub make_dependencies: Vec<PackageRelation>,
81
82 pub sources: Vec<MergedSource>,
84 pub no_extracts: Vec<String>,
86}
87
88#[derive(Clone, Debug)]
90pub struct MergedPackagesIterator<'a> {
91 pub(crate) architecture: Architecture,
92 pub(crate) source_info: &'a SourceInfoV1,
93 pub(crate) package_iterator: std::slice::Iter<'a, Package>,
94}
95
96impl Iterator for MergedPackagesIterator<'_> {
97 type Item = MergedPackage;
98
99 fn next(&mut self) -> Option<MergedPackage> {
100 let package = self.package_iterator.find(|package| {
102 let architectures = match &package.architectures {
105 Some(value) => value,
106 None => &self.source_info.base.architectures,
107 };
108
109 architectures.contains(&self.architecture) || architectures.contains(&Architecture::Any)
110 })?;
111
112 Some(MergedPackage::from_base_and_package(
113 self.architecture,
114 &self.source_info.base,
115 package,
116 ))
117 }
118}
119
120#[derive(Clone, Debug, Deserialize, Serialize)]
125pub struct MergedSource {
126 pub source: Source,
128 pub b2_checksum: Option<SkippableChecksum<Blake2b512>>,
130 pub md5_checksum: Option<SkippableChecksum<Md5>>,
132 pub sha1_checksum: Option<SkippableChecksum<Sha1>>,
134 pub sha224_checksum: Option<SkippableChecksum<Sha224>>,
136 pub sha256_checksum: Option<SkippableChecksum<Sha256>>,
138 pub sha384_checksum: Option<SkippableChecksum<Sha384>>,
140 pub sha512_checksum: Option<SkippableChecksum<Sha512>>,
142}
143
144#[derive(Clone, Debug)]
150pub struct MergedSourceIterator<'a> {
151 sources: std::slice::Iter<'a, Source>,
152 b2_checksums: std::slice::Iter<'a, SkippableChecksum<Blake2b512>>,
153 md5_checksums: std::slice::Iter<'a, SkippableChecksum<Md5>>,
154 sha1_checksums: std::slice::Iter<'a, SkippableChecksum<Sha1>>,
155 sha224_checksums: std::slice::Iter<'a, SkippableChecksum<Sha224>>,
156 sha256_checksums: std::slice::Iter<'a, SkippableChecksum<Sha256>>,
157 sha384_checksums: std::slice::Iter<'a, SkippableChecksum<Sha384>>,
158 sha512_checksums: std::slice::Iter<'a, SkippableChecksum<Sha512>>,
159}
160
161impl Iterator for MergedSourceIterator<'_> {
162 type Item = MergedSource;
163
164 fn next(&mut self) -> Option<MergedSource> {
165 let source = self.sources.next()?;
166
167 Some(MergedSource {
168 source: source.clone(),
169 b2_checksum: self.b2_checksums.next().cloned(),
170 md5_checksum: self.md5_checksums.next().cloned(),
171 sha1_checksum: self.sha1_checksums.next().cloned(),
172 sha224_checksum: self.sha224_checksums.next().cloned(),
173 sha256_checksum: self.sha256_checksums.next().cloned(),
174 sha384_checksum: self.sha384_checksums.next().cloned(),
175 sha512_checksum: self.sha512_checksums.next().cloned(),
176 })
177 }
178}
179
180impl MergedPackage {
181 pub fn from_base_and_package(
199 architecture: Architecture,
200 base: &PackageBase,
201 package: &Package,
202 ) -> MergedPackage {
203 let name = package.name.clone();
204 let mut merged_package = Self::from_base(&architecture, name, base);
206
207 merged_package.merge_package(package);
209
210 let mut architecture_properties =
213 if let Some(properties) = base.architecture_properties.get(&architecture) {
214 properties.clone()
215 } else {
216 PackageBaseArchitecture::default()
217 };
218
219 if let Some(package_properties) = package.architecture_properties.get(&architecture) {
221 architecture_properties.merge_package_properties(package_properties.clone());
222 }
223
224 merged_package.merge_architecture_properties(&architecture_properties);
226
227 merged_package
228 }
229
230 pub fn from_base(architecture: &Architecture, name: Name, base: &PackageBase) -> MergedPackage {
243 let merged_sources = MergedSourceIterator {
245 sources: base.sources.iter(),
246 b2_checksums: base.b2_checksums.iter(),
247 md5_checksums: base.md5_checksums.iter(),
248 sha1_checksums: base.sha1_checksums.iter(),
249 sha224_checksums: base.sha224_checksums.iter(),
250 sha256_checksums: base.sha256_checksums.iter(),
251 sha384_checksums: base.sha384_checksums.iter(),
252 sha512_checksums: base.sha512_checksums.iter(),
253 };
254
255 MergedPackage {
256 name,
257 description: base.description.clone(),
258 url: base.url.clone(),
259 licenses: base.licenses.clone(),
260 architecture: *architecture,
261 changelog: base.changelog.clone(),
262 install: base.install.clone(),
263 groups: base.groups.clone(),
264 options: base.options.clone(),
265 backups: base.backups.clone(),
266 version: base.version.clone(),
267 pgp_fingerprints: base.pgp_fingerprints.clone(),
268 dependencies: base.dependencies.clone(),
269 optional_dependencies: base.optional_dependencies.clone(),
270 provides: base.provides.clone(),
271 conflicts: base.conflicts.clone(),
272 replaces: base.replaces.clone(),
273 check_dependencies: base.check_dependencies.clone(),
274 make_dependencies: base.make_dependencies.clone(),
275 sources: merged_sources.collect(),
276 no_extracts: base.no_extracts.clone(),
277 }
278 }
279
280 pub fn merge_package(&mut self, package: &Package) {
284 let package = package.clone();
285 package.description.merge_option(&mut self.description);
286
287 package.url.merge_option(&mut self.url);
288 package.changelog.merge_option(&mut self.changelog);
289 package.licenses.merge_vec(&mut self.licenses);
290 package.install.merge_option(&mut self.install);
291 package.groups.merge_vec(&mut self.groups);
292 package.options.merge_vec(&mut self.options);
293 package.backups.merge_vec(&mut self.backups);
294 package.dependencies.merge_vec(&mut self.dependencies);
295 package
296 .optional_dependencies
297 .merge_vec(&mut self.optional_dependencies);
298 package.provides.merge_vec(&mut self.provides);
299 package.conflicts.merge_vec(&mut self.conflicts);
300 package.replaces.merge_vec(&mut self.replaces);
301 }
302
303 pub fn merge_architecture_properties(&mut self, base_architecture: &PackageBaseArchitecture) {
309 let merged_sources = MergedSourceIterator {
311 sources: base_architecture.sources.iter(),
312 b2_checksums: base_architecture.b2_checksums.iter(),
313 md5_checksums: base_architecture.md5_checksums.iter(),
314 sha1_checksums: base_architecture.sha1_checksums.iter(),
315 sha224_checksums: base_architecture.sha224_checksums.iter(),
316 sha256_checksums: base_architecture.sha256_checksums.iter(),
317 sha384_checksums: base_architecture.sha384_checksums.iter(),
318 sha512_checksums: base_architecture.sha512_checksums.iter(),
319 };
320
321 self.dependencies
322 .extend_from_slice(&base_architecture.dependencies);
323 self.optional_dependencies
324 .extend_from_slice(&base_architecture.optional_dependencies);
325 self.provides.extend_from_slice(&base_architecture.provides);
326 self.conflicts
327 .extend_from_slice(&base_architecture.conflicts);
328 self.replaces.extend_from_slice(&base_architecture.replaces);
329 self.check_dependencies
330 .extend_from_slice(&base_architecture.check_dependencies);
331 self.make_dependencies
332 .extend_from_slice(&base_architecture.make_dependencies);
333
334 self.sources
335 .extend_from_slice(&merged_sources.collect::<Vec<MergedSource>>());
336 }
337}