zoi/pkg/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
5#[serde(rename_all = "lowercase")]
6#[derive(Default)]
7pub enum Scope {
8    #[default]
9    User,
10    System,
11    Project,
12}
13
14#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Copy)]
15#[serde(rename_all = "lowercase")]
16#[derive(Default)]
17pub enum PackageType {
18    #[default]
19    Package,
20    Collection,
21    App,
22    Extension,
23}
24
25#[derive(Debug, Serialize, Deserialize, Clone)]
26#[serde(rename_all = "lowercase")]
27pub enum UpdateType {
28    Change,
29    Vulnerability,
30    Update,
31}
32
33#[derive(Debug, Serialize, Deserialize, Clone)]
34pub struct UpdateInfo {
35    #[serde(rename = "type")]
36    pub update_type: UpdateType,
37    pub message: String,
38}
39
40#[derive(Debug, Serialize, Deserialize, Clone)]
41#[serde(tag = "type")]
42#[serde(rename_all = "kebab-case")]
43pub enum ExtensionChange {
44    RepoGit { add: String },
45    RegistryRepo { add: String },
46    RegistryAdd { add: String },
47    RepoAdd { add: String },
48    Project { add: String },
49    Pgp { name: String, key: String },
50}
51
52#[derive(Debug, Serialize, Deserialize, Clone)]
53pub struct ExtensionInfo {
54    #[serde(rename = "type")]
55    pub extension_type: String,
56    pub changes: Vec<ExtensionChange>,
57}
58
59#[derive(Debug, Serialize, Deserialize, Clone)]
60#[allow(dead_code)]
61pub struct Package {
62    pub name: String,
63    pub repo: String,
64    pub version: Option<String>,
65    #[serde(default, skip_serializing_if = "Option::is_none")]
66    pub sub_packages: Option<Vec<String>>,
67    #[serde(default, skip_serializing_if = "Option::is_none")]
68    pub main_subs: Option<Vec<String>>,
69    pub versions: Option<HashMap<String, String>>,
70    pub description: String,
71    pub website: Option<String>,
72    #[serde(default)]
73    pub readme: Option<String>,
74    #[serde(default)]
75    pub man: Option<String>,
76    #[serde(default)]
77    pub git: String,
78    pub maintainer: Maintainer,
79    pub author: Option<Author>,
80    #[serde(default)]
81    pub license: String,
82    #[serde(default)]
83    pub types: Vec<String>,
84    pub dependencies: Option<Dependencies>,
85    #[serde(rename = "type", default)]
86    pub package_type: PackageType,
87    pub alt: Option<String>,
88    #[serde(default)]
89    pub scope: Scope,
90    #[serde(default)]
91    pub bins: Option<Vec<String>>,
92    #[serde(default, skip_serializing_if = "Option::is_none")]
93    pub conflicts: Option<Vec<String>>,
94    #[serde(default, skip_serializing_if = "Option::is_none")]
95    pub replaces: Option<Vec<String>>,
96    #[serde(default, skip_serializing_if = "Option::is_none")]
97    pub provides: Option<Vec<String>>,
98    #[serde(default)]
99    pub tags: Vec<String>,
100    #[serde(default)]
101    pub extension: Option<ExtensionInfo>,
102    #[serde(default)]
103    pub rollback: Option<bool>,
104    #[serde(default)]
105    pub updates: Option<Vec<UpdateInfo>>,
106    #[serde(default)]
107    pub hooks: Option<Hooks>,
108    #[serde(default, skip_serializing_if = "Option::is_none")]
109    pub backup: Option<Vec<String>>,
110
111    #[serde(default, skip_serializing_if = "Option::is_none")]
112    pub installed_size: Option<u64>,
113    #[serde(default, skip_serializing_if = "Option::is_none")]
114    pub archive_size: Option<u64>,
115}
116
117#[derive(Debug, Serialize, Deserialize, Clone)]
118#[serde(untagged)]
119pub enum PlatformOrStringVec {
120    StringVec(Vec<String>),
121    Platform(HashMap<String, Vec<String>>),
122}
123
124#[derive(Debug, Serialize, Deserialize, Clone, Default)]
125pub struct Hooks {
126    #[serde(default, skip_serializing_if = "Option::is_none")]
127    pub pre_install: Option<PlatformOrStringVec>,
128    #[serde(default, skip_serializing_if = "Option::is_none")]
129    pub post_install: Option<PlatformOrStringVec>,
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub pre_upgrade: Option<PlatformOrStringVec>,
132    #[serde(default, skip_serializing_if = "Option::is_none")]
133    pub post_upgrade: Option<PlatformOrStringVec>,
134    #[serde(default, skip_serializing_if = "Option::is_none")]
135    pub pre_remove: Option<PlatformOrStringVec>,
136    #[serde(default, skip_serializing_if = "Option::is_none")]
137    pub post_remove: Option<PlatformOrStringVec>,
138}
139
140#[derive(Debug, Serialize, Deserialize, Clone)]
141#[allow(dead_code)]
142pub struct Maintainer {
143    pub name: String,
144    pub email: String,
145    pub website: Option<String>,
146}
147
148#[derive(Debug, Serialize, Deserialize, Clone)]
149#[allow(dead_code)]
150pub struct Author {
151    pub name: String,
152    pub email: Option<String>,
153    pub website: Option<String>,
154}
155
156#[derive(Debug, Serialize, Deserialize, Clone)]
157#[allow(dead_code)]
158pub struct DependencyOptionGroup {
159    pub name: String,
160    pub desc: String,
161    #[serde(default)]
162    pub all: bool,
163    pub depends: Vec<String>,
164}
165
166#[derive(Debug, Serialize, Deserialize, Clone)]
167#[serde(untagged)]
168pub enum DependencyGroup {
169    Simple(Vec<String>),
170    Complex(ComplexDependencyGroup),
171}
172
173impl DependencyGroup {
174    pub fn get_required_simple(&self) -> Vec<String> {
175        match self {
176            DependencyGroup::Simple(deps) => deps.clone(),
177            DependencyGroup::Complex(group) => group.required.clone(),
178        }
179    }
180
181    pub fn get_required_options(&self) -> Vec<DependencyOptionGroup> {
182        match self {
183            DependencyGroup::Simple(_) => Vec::new(),
184            DependencyGroup::Complex(group) => group.options.clone(),
185        }
186    }
187
188    pub fn get_optional(&self) -> &Vec<String> {
189        match self {
190            DependencyGroup::Simple(_) => {
191                static EMPTY_VEC: Vec<String> = Vec::new();
192                &EMPTY_VEC
193            }
194            DependencyGroup::Complex(group) => &group.optional,
195        }
196    }
197}
198
199#[derive(Debug, Serialize, Deserialize, Clone, Default)]
200pub struct ComplexDependencyGroup {
201    #[serde(default)]
202    pub required: Vec<String>,
203    #[serde(default)]
204    pub options: Vec<DependencyOptionGroup>,
205    #[serde(default)]
206    pub optional: Vec<String>,
207    #[serde(default, skip_serializing_if = "Option::is_none")]
208    pub sub_packages: Option<HashMap<String, DependencyGroup>>,
209}
210
211#[derive(Debug, Serialize, Deserialize, Clone, Default)]
212pub struct TypedBuildDependencies {
213    pub types: HashMap<String, DependencyGroup>,
214}
215
216#[derive(Debug, Serialize, Deserialize, Clone)]
217#[serde(untagged)]
218pub enum BuildDependencies {
219    Typed(TypedBuildDependencies),
220    Group(DependencyGroup),
221}
222
223#[derive(Debug, Serialize, Deserialize, Clone)]
224pub struct Dependencies {
225    #[serde(default)]
226    pub runtime: Option<DependencyGroup>,
227    #[serde(default)]
228    pub build: Option<BuildDependencies>,
229}
230
231#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
232pub enum InstallReason {
233    Direct,
234    Dependency { parent: String },
235}
236
237#[derive(Debug, Serialize, Deserialize, Clone)]
238pub struct InstallManifest {
239    pub name: String,
240    pub version: String,
241    #[serde(default, skip_serializing_if = "Option::is_none")]
242    pub sub_package: Option<String>,
243    pub repo: String,
244    pub registry_handle: String,
245    pub package_type: PackageType,
246    pub reason: InstallReason,
247    pub scope: Scope,
248    pub bins: Option<Vec<String>>,
249    #[serde(default, skip_serializing_if = "Option::is_none")]
250    pub conflicts: Option<Vec<String>>,
251    #[serde(default, skip_serializing_if = "Option::is_none")]
252    pub replaces: Option<Vec<String>>,
253    #[serde(default, skip_serializing_if = "Option::is_none")]
254    pub provides: Option<Vec<String>>,
255    #[serde(default, skip_serializing_if = "Option::is_none")]
256    pub backup: Option<Vec<String>>,
257    #[serde(default)]
258    pub installed_dependencies: Vec<String>,
259    #[serde(default)]
260    pub chosen_options: Vec<String>,
261    #[serde(default)]
262    pub chosen_optionals: Vec<String>,
263    #[serde(default)]
264    pub install_method: Option<String>,
265    #[serde(default)]
266    pub installed_files: Vec<String>,
267    #[serde(default, skip_serializing_if = "Option::is_none")]
268    pub installed_size: Option<u64>,
269}
270
271#[derive(Debug, Serialize, Deserialize, Clone)]
272#[serde(rename_all = "camelCase")]
273pub enum TransactionOperation {
274    Install {
275        manifest: Box<InstallManifest>,
276    },
277    Uninstall {
278        manifest: Box<InstallManifest>,
279    },
280    Upgrade {
281        old_manifest: Box<InstallManifest>,
282        new_manifest: Box<InstallManifest>,
283    },
284}
285
286#[derive(Debug, Serialize, Deserialize, Clone)]
287pub struct Transaction {
288    pub id: String,
289    pub start_time: String,
290    pub operations: Vec<TransactionOperation>,
291}
292
293#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
294pub struct Registry {
295    pub handle: String,
296    pub url: String,
297}
298
299#[derive(Debug, Serialize, Deserialize, Default, Clone)]
300pub struct Config {
301    pub repos: Vec<String>,
302    pub package_managers: Option<Vec<String>>,
303    pub native_package_manager: Option<String>,
304    #[serde(default)]
305    pub telemetry_enabled: bool,
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub registry: Option<String>,
308    #[serde(default)]
309    pub default_registry: Option<Registry>,
310    #[serde(default)]
311    pub added_registries: Vec<Registry>,
312    #[serde(default)]
313    pub git_repos: Vec<String>,
314    #[serde(default)]
315    pub rollback_enabled: bool,
316    #[serde(default)]
317    pub policy: Policy,
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub parallel_jobs: Option<usize>,
320    #[serde(default)]
321    pub protect_db: bool,
322}
323
324#[derive(Debug, Serialize, Deserialize, Clone, Default)]
325pub struct Policy {
326    #[serde(default, skip_serializing_if = "is_false")]
327    pub repos_unoverridable: bool,
328    #[serde(default, skip_serializing_if = "is_false")]
329    pub telemetry_enabled_unoverridable: bool,
330    #[serde(default, skip_serializing_if = "is_false")]
331    pub rollback_enabled_unoverridable: bool,
332    #[serde(default, skip_serializing_if = "is_false")]
333    pub default_registry_unoverridable: bool,
334    #[serde(default, skip_serializing_if = "is_false")]
335    pub added_registries_unoverridable: bool,
336    #[serde(default, skip_serializing_if = "is_false")]
337    pub git_repos_unoverridable: bool,
338    #[serde(default, skip_serializing_if = "is_false")]
339    pub allow_deny_lists_unoverridable: bool,
340    #[serde(default, skip_serializing_if = "is_false")]
341    pub signature_enforcement_unoverridable: bool,
342    #[serde(default, skip_serializing_if = "is_false")]
343    pub protect_db_unoverridable: bool,
344
345    #[serde(default, skip_serializing_if = "Option::is_none")]
346    pub allowed_licenses: Option<Vec<String>>,
347    #[serde(default, skip_serializing_if = "Option::is_none")]
348    pub denied_licenses: Option<Vec<String>>,
349
350    #[serde(default, skip_serializing_if = "Option::is_none")]
351    pub allowed_packages: Option<Vec<String>>,
352    #[serde(default, skip_serializing_if = "Option::is_none")]
353    pub denied_packages: Option<Vec<String>>,
354
355    #[serde(default, skip_serializing_if = "Option::is_none")]
356    pub allowed_repos: Option<Vec<String>>,
357    #[serde(default, skip_serializing_if = "Option::is_none")]
358    pub denied_repos: Option<Vec<String>>,
359
360    #[serde(default, skip_serializing_if = "Option::is_none")]
361    pub signature_enforcement: Option<SignatureEnforcementPolicy>,
362}
363
364#[derive(Debug, Serialize, Deserialize, Clone, Default)]
365pub struct SignatureEnforcementPolicy {
366    #[serde(default)]
367    pub enable: bool,
368    #[serde(default)]
369    pub trusted_keys: Vec<String>,
370}
371
372fn is_false(b: &bool) -> bool {
373    !*b
374}
375
376#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
377pub struct SharableInstallManifest {
378    pub name: String,
379    pub version: String,
380    pub repo: String,
381    pub registry_handle: String,
382    pub scope: Scope,
383    #[serde(default, skip_serializing_if = "Vec::is_empty")]
384    pub chosen_options: Vec<String>,
385    #[serde(default, skip_serializing_if = "Vec::is_empty")]
386    pub chosen_optionals: Vec<String>,
387}
388
389#[derive(Debug, Serialize, Deserialize, Clone)]
390pub struct ZoiLockOld {
391    pub packages: HashMap<String, String>,
392}
393
394#[derive(Debug, Serialize, Deserialize, Clone, Default)]
395pub struct ZoiLock {
396    pub version: String,
397    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
398    pub registries: HashMap<String, String>,
399    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
400    pub packages: HashMap<String, String>,
401    #[serde(flatten)]
402    pub details: HashMap<String, HashMap<String, LockPackageDetail>>,
403}
404
405#[derive(Debug, Serialize, Deserialize, Clone)]
406pub struct LockPackageDetail {
407    pub version: String,
408    #[serde(default, skip_serializing_if = "Option::is_none")]
409    pub sub_package: Option<String>,
410    pub integrity: String,
411    #[serde(default, skip_serializing_if = "Vec::is_empty")]
412    pub dependencies: Vec<String>,
413    #[serde(default, skip_serializing_if = "Vec::is_empty")]
414    pub options_dependencies: Vec<String>,
415    #[serde(default, skip_serializing_if = "Vec::is_empty")]
416    pub optionals_dependencies: Vec<String>,
417}
418
419#[derive(Debug, Serialize, Deserialize, Clone)]
420pub struct Lockfile {
421    pub version: String,
422    pub packages: HashMap<String, LockfilePackage>,
423}
424
425#[derive(Debug, Serialize, Deserialize, Clone)]
426pub struct LockfilePackage {
427    pub name: String,
428    #[serde(default, skip_serializing_if = "Option::is_none")]
429    pub sub_package: Option<String>,
430    pub repo: String,
431    pub registry: String,
432    pub version: String,
433    pub date: String,
434    pub reason: InstallReason,
435    pub scope: Scope,
436    #[serde(default, skip_serializing_if = "Option::is_none")]
437    pub bins: Option<Vec<String>>,
438    #[serde(default, skip_serializing_if = "Option::is_none")]
439    pub conflicts: Option<Vec<String>>,
440    #[serde(default, skip_serializing_if = "Option::is_none")]
441    pub replaces: Option<Vec<String>>,
442    #[serde(default, skip_serializing_if = "Option::is_none")]
443    pub provides: Option<Vec<String>>,
444    #[serde(default, skip_serializing_if = "Option::is_none")]
445    pub backup: Option<Vec<String>>,
446    #[serde(default, skip_serializing_if = "Vec::is_empty")]
447    pub dependencies: Vec<String>,
448    #[serde(default, skip_serializing_if = "Vec::is_empty")]
449    pub chosen_options: Vec<String>,
450    #[serde(default, skip_serializing_if = "Vec::is_empty")]
451    pub chosen_optionals: Vec<String>,
452}
453
454#[derive(Debug, Serialize, Deserialize, Clone)]
455pub struct GitLink {
456    #[serde(rename = "type")]
457    pub link_type: String,
458    pub url: String,
459}
460
461#[derive(Debug, Serialize, Deserialize, Clone)]
462pub struct PkgLink {
463    #[serde(rename = "type")]
464    pub link_type: String,
465    pub url: String,
466    pub pgp: Option<String>,
467    pub hash: Option<String>,
468    pub size: Option<String>,
469}
470
471#[derive(Debug, Serialize, Deserialize, Clone)]
472pub struct PgpKey {
473    pub name: String,
474    pub key: String,
475}
476
477#[derive(Debug, Serialize, Deserialize, Clone)]
478pub struct RepoEntry {
479    pub name: String,
480    #[serde(rename = "type")]
481    pub repo_type: String,
482    pub active: bool,
483}
484
485#[derive(Debug, Serialize, Deserialize, Clone)]
486pub struct RepoConfig {
487    pub name: String,
488    pub description: String,
489    pub git: Vec<GitLink>,
490    #[serde(default)]
491    pub pkg: Vec<PkgLink>,
492    #[serde(default)]
493    pub pgp: Vec<PgpKey>,
494    pub repos: Vec<RepoEntry>,
495}
496
497#[derive(Debug, Clone)]
498pub struct PrebuiltInfo {
499    pub final_url: String,
500    pub pgp_url: Option<String>,
501    pub hash_url: Option<String>,
502    pub size_url: Option<String>,
503}