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 RelativePath,
15 SkippableChecksum,
16 Source,
17 Url,
18 digests::{Blake2b512, 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 relation::RelationOrSoname,
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,
41 pub description: Option<PackageDescription>,
42 pub url: Option<Url>,
43 pub licenses: Vec<License>,
44 pub architecture: Architecture,
45 pub changelog: Option<RelativePath>,
46
47 pub install: Option<RelativePath>,
49 pub groups: Vec<String>,
50 pub options: Vec<MakepkgOption>,
51 pub backups: Vec<RelativePath>,
52
53 pub package_version: PackageVersion,
55 pub package_release: PackageRelease,
57 pub epoch: Option<Epoch>,
59 pub pgp_fingerprints: Vec<OpenPGPIdentifier>,
60
61 pub dependencies: Vec<RelationOrSoname>,
62 pub optional_dependencies: Vec<OptionalDependency>,
63 pub provides: Vec<RelationOrSoname>,
64 pub conflicts: Vec<PackageRelation>,
65 pub replaces: Vec<PackageRelation>,
66 pub check_dependencies: Vec<PackageRelation>,
67 pub make_dependencies: Vec<PackageRelation>,
68
69 pub sources: Vec<MergedSource>,
70 pub no_extracts: Vec<String>,
71}
72
73pub struct MergedPackagesIterator<'a> {
75 pub(crate) architecture: Architecture,
76 pub(crate) source_info: &'a SourceInfoV1,
77 pub(crate) package_iterator: std::slice::Iter<'a, Package>,
78}
79
80impl Iterator for MergedPackagesIterator<'_> {
81 type Item = MergedPackage;
82
83 fn next(&mut self) -> Option<MergedPackage> {
84 let package = self.package_iterator.find(|package| {
86 let architectures = match &package.architectures {
89 Some(value) => value,
90 None => &self.source_info.base.architectures,
91 };
92
93 architectures.contains(&self.architecture) || architectures.contains(&Architecture::Any)
94 })?;
95
96 Some(MergedPackage::from_base_and_package(
97 self.architecture,
98 &self.source_info.base,
99 package,
100 ))
101 }
102}
103
104#[derive(Clone, Debug, Deserialize, Serialize)]
109pub struct MergedSource {
110 pub source: Source,
111 pub b2_checksum: Option<SkippableChecksum<Blake2b512>>,
112 pub md5_checksum: Option<SkippableChecksum<Md5>>,
113 pub sha1_checksum: Option<SkippableChecksum<Sha1>>,
114 pub sha224_checksum: Option<SkippableChecksum<Sha224>>,
115 pub sha256_checksum: Option<SkippableChecksum<Sha256>>,
116 pub sha384_checksum: Option<SkippableChecksum<Sha384>>,
117 pub sha512_checksum: Option<SkippableChecksum<Sha512>>,
118}
119
120pub struct MergedSourceIterator<'a> {
126 sources: std::slice::Iter<'a, Source>,
127 b2_checksums: std::slice::Iter<'a, SkippableChecksum<Blake2b512>>,
128 md5_checksums: std::slice::Iter<'a, SkippableChecksum<Md5>>,
129 sha1_checksums: std::slice::Iter<'a, SkippableChecksum<Sha1>>,
130 sha224_checksums: std::slice::Iter<'a, SkippableChecksum<Sha224>>,
131 sha256_checksums: std::slice::Iter<'a, SkippableChecksum<Sha256>>,
132 sha384_checksums: std::slice::Iter<'a, SkippableChecksum<Sha384>>,
133 sha512_checksums: std::slice::Iter<'a, SkippableChecksum<Sha512>>,
134}
135
136impl Iterator for MergedSourceIterator<'_> {
137 type Item = MergedSource;
138
139 fn next(&mut self) -> Option<MergedSource> {
140 let source = self.sources.next()?;
141
142 Some(MergedSource {
143 source: source.clone(),
144 b2_checksum: self.b2_checksums.next().cloned(),
145 md5_checksum: self.md5_checksums.next().cloned(),
146 sha1_checksum: self.sha1_checksums.next().cloned(),
147 sha224_checksum: self.sha224_checksums.next().cloned(),
148 sha256_checksum: self.sha256_checksums.next().cloned(),
149 sha384_checksum: self.sha384_checksums.next().cloned(),
150 sha512_checksum: self.sha512_checksums.next().cloned(),
151 })
152 }
153}
154
155impl MergedPackage {
156 pub fn from_base_and_package(
174 architecture: Architecture,
175 base: &PackageBase,
176 package: &Package,
177 ) -> MergedPackage {
178 let name = package.name.clone();
179 let mut merged_package = Self::from_base(&architecture, name, base);
181
182 merged_package.merge_package(package);
184
185 let mut architecture_properties =
188 if let Some(properties) = base.architecture_properties.get(&architecture) {
189 properties.clone()
190 } else {
191 PackageBaseArchitecture::default()
192 };
193
194 if let Some(package_properties) = package.architecture_properties.get(&architecture) {
196 architecture_properties.merge_package_properties(package_properties.clone());
197 }
198
199 merged_package.merge_architecture_properties(&architecture_properties);
201
202 merged_package
203 }
204
205 pub fn from_base(architecture: &Architecture, name: Name, base: &PackageBase) -> MergedPackage {
218 let merged_sources = MergedSourceIterator {
220 sources: base.sources.iter(),
221 b2_checksums: base.b2_checksums.iter(),
222 md5_checksums: base.md5_checksums.iter(),
223 sha1_checksums: base.sha1_checksums.iter(),
224 sha224_checksums: base.sha224_checksums.iter(),
225 sha256_checksums: base.sha256_checksums.iter(),
226 sha384_checksums: base.sha384_checksums.iter(),
227 sha512_checksums: base.sha512_checksums.iter(),
228 };
229
230 MergedPackage {
231 name,
232 description: base.description.clone(),
233 url: base.url.clone(),
234 licenses: base.licenses.clone(),
235 architecture: *architecture,
236 changelog: base.changelog.clone(),
237 install: base.install.clone(),
238 groups: base.groups.clone(),
239 options: base.options.clone(),
240 backups: base.backups.clone(),
241 package_version: base.package_version.clone(),
242 package_release: base.package_release.clone(),
243 epoch: base.epoch,
244 pgp_fingerprints: base.pgp_fingerprints.clone(),
245 dependencies: base.dependencies.clone(),
246 optional_dependencies: base.optional_dependencies.clone(),
247 provides: base.provides.clone(),
248 conflicts: base.conflicts.clone(),
249 replaces: base.replaces.clone(),
250 check_dependencies: base.check_dependencies.clone(),
251 make_dependencies: base.make_dependencies.clone(),
252 sources: merged_sources.collect(),
253 no_extracts: base.no_extracts.clone(),
254 }
255 }
256
257 pub fn merge_package(&mut self, package: &Package) {
261 let package = package.clone();
262 package.description.merge_option(&mut self.description);
263
264 package.url.merge_option(&mut self.url);
265 package.changelog.merge_option(&mut self.changelog);
266 package.licenses.merge_vec(&mut self.licenses);
267 package.install.merge_option(&mut self.install);
268 package.groups.merge_vec(&mut self.groups);
269 package.options.merge_vec(&mut self.options);
270 package.backups.merge_vec(&mut self.backups);
271 package.dependencies.merge_vec(&mut self.dependencies);
272 package
273 .optional_dependencies
274 .merge_vec(&mut self.optional_dependencies);
275 package.provides.merge_vec(&mut self.provides);
276 package.conflicts.merge_vec(&mut self.conflicts);
277 package.replaces.merge_vec(&mut self.replaces);
278 }
279
280 pub fn merge_architecture_properties(&mut self, base_architecture: &PackageBaseArchitecture) {
286 let merged_sources = MergedSourceIterator {
288 sources: base_architecture.sources.iter(),
289 b2_checksums: base_architecture.b2_checksums.iter(),
290 md5_checksums: base_architecture.md5_checksums.iter(),
291 sha1_checksums: base_architecture.sha1_checksums.iter(),
292 sha224_checksums: base_architecture.sha224_checksums.iter(),
293 sha256_checksums: base_architecture.sha256_checksums.iter(),
294 sha384_checksums: base_architecture.sha384_checksums.iter(),
295 sha512_checksums: base_architecture.sha512_checksums.iter(),
296 };
297
298 self.dependencies
299 .extend_from_slice(&base_architecture.dependencies);
300 self.optional_dependencies
301 .extend_from_slice(&base_architecture.optional_dependencies);
302 self.provides.extend_from_slice(&base_architecture.provides);
303 self.conflicts
304 .extend_from_slice(&base_architecture.conflicts);
305 self.replaces.extend_from_slice(&base_architecture.replaces);
306 self.check_dependencies
307 .extend_from_slice(&base_architecture.check_dependencies);
308 self.make_dependencies
309 .extend_from_slice(&base_architecture.make_dependencies);
310
311 self.sources
312 .extend_from_slice(&merged_sources.collect::<Vec<MergedSource>>());
313 self.no_extracts
314 .extend_from_slice(&base_architecture.no_extracts);
315 }
316}