alpm_srcinfo/source_info/v1/
merged.rs1use alpm_types::{
3 Architecture,
4 Epoch,
5 License,
6 MakepkgOption,
7 Name,
8 OpenPGPIdentifier,
9 OptionalDependency,
10 PackageDescription,
11 PackageRelation,
12 PackageRelease,
13 PackageVersion,
14 RelationOrSoname,
15 RelativePath,
16 SkippableChecksum,
17 Source,
18 Url,
19 digests::{Blake2b512, Md5, Sha1, Sha224, Sha256, Sha384, Sha512},
20};
21use serde::{Deserialize, Serialize};
22
23#[cfg(doc)]
24use crate::source_info::v1::package::Override;
25use crate::{
26 SourceInfoV1,
27 source_info::v1::{
28 package::Package,
29 package_base::{PackageBase, PackageBaseArchitecture},
30 },
31};
32
33#[derive(Clone, Debug, Deserialize, Serialize)]
39pub struct MergedPackage {
40 pub name: Name,
42 pub description: Option<PackageDescription>,
44 pub url: Option<Url>,
46 pub licenses: Vec<License>,
48 pub architecture: Architecture,
50 pub changelog: Option<RelativePath>,
52
53 pub install: Option<RelativePath>,
56 pub groups: Vec<String>,
58 pub options: Vec<MakepkgOption>,
60 pub backups: Vec<RelativePath>,
62
63 pub package_version: PackageVersion,
65 pub package_release: PackageRelease,
67 pub epoch: Option<Epoch>,
69 pub pgp_fingerprints: Vec<OpenPGPIdentifier>,
72
73 pub dependencies: Vec<RelationOrSoname>,
75 pub optional_dependencies: Vec<OptionalDependency>,
77 pub provides: Vec<RelationOrSoname>,
79 pub conflicts: Vec<PackageRelation>,
81 pub replaces: Vec<PackageRelation>,
83 pub check_dependencies: Vec<PackageRelation>,
85 pub make_dependencies: Vec<PackageRelation>,
87
88 pub sources: Vec<MergedSource>,
90 pub no_extracts: Vec<String>,
92}
93
94#[derive(Clone, Debug)]
96pub struct MergedPackagesIterator<'a> {
97 pub(crate) architecture: Architecture,
98 pub(crate) source_info: &'a SourceInfoV1,
99 pub(crate) package_iterator: std::slice::Iter<'a, Package>,
100}
101
102impl Iterator for MergedPackagesIterator<'_> {
103 type Item = MergedPackage;
104
105 fn next(&mut self) -> Option<MergedPackage> {
106 let package = self.package_iterator.find(|package| {
108 let architectures = match &package.architectures {
111 Some(value) => value,
112 None => &self.source_info.base.architectures,
113 };
114
115 architectures.contains(&self.architecture) || architectures.contains(&Architecture::Any)
116 })?;
117
118 Some(MergedPackage::from_base_and_package(
119 self.architecture,
120 &self.source_info.base,
121 package,
122 ))
123 }
124}
125
126#[derive(Clone, Debug, Deserialize, Serialize)]
131pub struct MergedSource {
132 pub source: Source,
134 pub b2_checksum: Option<SkippableChecksum<Blake2b512>>,
136 pub md5_checksum: Option<SkippableChecksum<Md5>>,
138 pub sha1_checksum: Option<SkippableChecksum<Sha1>>,
140 pub sha224_checksum: Option<SkippableChecksum<Sha224>>,
142 pub sha256_checksum: Option<SkippableChecksum<Sha256>>,
144 pub sha384_checksum: Option<SkippableChecksum<Sha384>>,
146 pub sha512_checksum: Option<SkippableChecksum<Sha512>>,
148}
149
150#[derive(Clone, Debug)]
156pub struct MergedSourceIterator<'a> {
157 sources: std::slice::Iter<'a, Source>,
158 b2_checksums: std::slice::Iter<'a, SkippableChecksum<Blake2b512>>,
159 md5_checksums: std::slice::Iter<'a, SkippableChecksum<Md5>>,
160 sha1_checksums: std::slice::Iter<'a, SkippableChecksum<Sha1>>,
161 sha224_checksums: std::slice::Iter<'a, SkippableChecksum<Sha224>>,
162 sha256_checksums: std::slice::Iter<'a, SkippableChecksum<Sha256>>,
163 sha384_checksums: std::slice::Iter<'a, SkippableChecksum<Sha384>>,
164 sha512_checksums: std::slice::Iter<'a, SkippableChecksum<Sha512>>,
165}
166
167impl Iterator for MergedSourceIterator<'_> {
168 type Item = MergedSource;
169
170 fn next(&mut self) -> Option<MergedSource> {
171 let source = self.sources.next()?;
172
173 Some(MergedSource {
174 source: source.clone(),
175 b2_checksum: self.b2_checksums.next().cloned(),
176 md5_checksum: self.md5_checksums.next().cloned(),
177 sha1_checksum: self.sha1_checksums.next().cloned(),
178 sha224_checksum: self.sha224_checksums.next().cloned(),
179 sha256_checksum: self.sha256_checksums.next().cloned(),
180 sha384_checksum: self.sha384_checksums.next().cloned(),
181 sha512_checksum: self.sha512_checksums.next().cloned(),
182 })
183 }
184}
185
186impl MergedPackage {
187 pub fn from_base_and_package(
205 architecture: Architecture,
206 base: &PackageBase,
207 package: &Package,
208 ) -> MergedPackage {
209 let name = package.name.clone();
210 let mut merged_package = Self::from_base(&architecture, name, base);
212
213 merged_package.merge_package(package);
215
216 let mut architecture_properties =
219 if let Some(properties) = base.architecture_properties.get(&architecture) {
220 properties.clone()
221 } else {
222 PackageBaseArchitecture::default()
223 };
224
225 if let Some(package_properties) = package.architecture_properties.get(&architecture) {
227 architecture_properties.merge_package_properties(package_properties.clone());
228 }
229
230 merged_package.merge_architecture_properties(&architecture_properties);
232
233 merged_package
234 }
235
236 pub fn from_base(architecture: &Architecture, name: Name, base: &PackageBase) -> MergedPackage {
249 let merged_sources = MergedSourceIterator {
251 sources: base.sources.iter(),
252 b2_checksums: base.b2_checksums.iter(),
253 md5_checksums: base.md5_checksums.iter(),
254 sha1_checksums: base.sha1_checksums.iter(),
255 sha224_checksums: base.sha224_checksums.iter(),
256 sha256_checksums: base.sha256_checksums.iter(),
257 sha384_checksums: base.sha384_checksums.iter(),
258 sha512_checksums: base.sha512_checksums.iter(),
259 };
260
261 MergedPackage {
262 name,
263 description: base.description.clone(),
264 url: base.url.clone(),
265 licenses: base.licenses.clone(),
266 architecture: *architecture,
267 changelog: base.changelog.clone(),
268 install: base.install.clone(),
269 groups: base.groups.clone(),
270 options: base.options.clone(),
271 backups: base.backups.clone(),
272 package_version: base.package_version.clone(),
273 package_release: base.package_release.clone(),
274 epoch: base.epoch,
275 pgp_fingerprints: base.pgp_fingerprints.clone(),
276 dependencies: base.dependencies.clone(),
277 optional_dependencies: base.optional_dependencies.clone(),
278 provides: base.provides.clone(),
279 conflicts: base.conflicts.clone(),
280 replaces: base.replaces.clone(),
281 check_dependencies: base.check_dependencies.clone(),
282 make_dependencies: base.make_dependencies.clone(),
283 sources: merged_sources.collect(),
284 no_extracts: base.no_extracts.clone(),
285 }
286 }
287
288 pub fn merge_package(&mut self, package: &Package) {
292 let package = package.clone();
293 package.description.merge_option(&mut self.description);
294
295 package.url.merge_option(&mut self.url);
296 package.changelog.merge_option(&mut self.changelog);
297 package.licenses.merge_vec(&mut self.licenses);
298 package.install.merge_option(&mut self.install);
299 package.groups.merge_vec(&mut self.groups);
300 package.options.merge_vec(&mut self.options);
301 package.backups.merge_vec(&mut self.backups);
302 package.dependencies.merge_vec(&mut self.dependencies);
303 package
304 .optional_dependencies
305 .merge_vec(&mut self.optional_dependencies);
306 package.provides.merge_vec(&mut self.provides);
307 package.conflicts.merge_vec(&mut self.conflicts);
308 package.replaces.merge_vec(&mut self.replaces);
309 }
310
311 pub fn merge_architecture_properties(&mut self, base_architecture: &PackageBaseArchitecture) {
317 let merged_sources = MergedSourceIterator {
319 sources: base_architecture.sources.iter(),
320 b2_checksums: base_architecture.b2_checksums.iter(),
321 md5_checksums: base_architecture.md5_checksums.iter(),
322 sha1_checksums: base_architecture.sha1_checksums.iter(),
323 sha224_checksums: base_architecture.sha224_checksums.iter(),
324 sha256_checksums: base_architecture.sha256_checksums.iter(),
325 sha384_checksums: base_architecture.sha384_checksums.iter(),
326 sha512_checksums: base_architecture.sha512_checksums.iter(),
327 };
328
329 self.dependencies
330 .extend_from_slice(&base_architecture.dependencies);
331 self.optional_dependencies
332 .extend_from_slice(&base_architecture.optional_dependencies);
333 self.provides.extend_from_slice(&base_architecture.provides);
334 self.conflicts
335 .extend_from_slice(&base_architecture.conflicts);
336 self.replaces.extend_from_slice(&base_architecture.replaces);
337 self.check_dependencies
338 .extend_from_slice(&base_architecture.check_dependencies);
339 self.make_dependencies
340 .extend_from_slice(&base_architecture.make_dependencies);
341
342 self.sources
343 .extend_from_slice(&merged_sources.collect::<Vec<MergedSource>>());
344 }
345}