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)]
212pub struct Dependencies {
213    #[serde(default)]
214    pub runtime: Option<DependencyGroup>,
215    #[serde(default)]
216    pub build: Option<DependencyGroup>,
217}
218
219#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
220pub enum InstallReason {
221    Direct,
222    Dependency { parent: String },
223}
224
225#[derive(Debug, Serialize, Deserialize, Clone)]
226pub struct InstallManifest {
227    pub name: String,
228    pub version: String,
229    #[serde(default, skip_serializing_if = "Option::is_none")]
230    pub sub_package: Option<String>,
231    pub repo: String,
232    pub registry_handle: String,
233    pub package_type: PackageType,
234    pub reason: InstallReason,
235    pub scope: Scope,
236    pub bins: Option<Vec<String>>,
237    #[serde(default, skip_serializing_if = "Option::is_none")]
238    pub conflicts: Option<Vec<String>>,
239    #[serde(default, skip_serializing_if = "Option::is_none")]
240    pub replaces: Option<Vec<String>>,
241    #[serde(default, skip_serializing_if = "Option::is_none")]
242    pub provides: Option<Vec<String>>,
243    #[serde(default, skip_serializing_if = "Option::is_none")]
244    pub backup: Option<Vec<String>>,
245    #[serde(default)]
246    pub installed_dependencies: Vec<String>,
247    #[serde(default)]
248    pub chosen_options: Vec<String>,
249    #[serde(default)]
250    pub chosen_optionals: Vec<String>,
251    #[serde(default)]
252    pub install_method: Option<String>,
253    #[serde(default)]
254    pub installed_files: Vec<String>,
255    #[serde(default, skip_serializing_if = "Option::is_none")]
256    pub installed_size: Option<u64>,
257}
258
259#[derive(Debug, Serialize, Deserialize, Clone)]
260#[serde(rename_all = "camelCase")]
261pub enum TransactionOperation {
262    Install {
263        manifest: Box<InstallManifest>,
264    },
265    Uninstall {
266        manifest: Box<InstallManifest>,
267    },
268    Upgrade {
269        old_manifest: Box<InstallManifest>,
270        new_manifest: Box<InstallManifest>,
271    },
272}
273
274#[derive(Debug, Serialize, Deserialize, Clone)]
275pub struct Transaction {
276    pub id: String,
277    pub start_time: String,
278    pub operations: Vec<TransactionOperation>,
279}
280
281#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
282pub struct Registry {
283    pub handle: String,
284    pub url: String,
285}
286
287#[derive(Debug, Serialize, Deserialize, Default, Clone)]
288pub struct Config {
289    pub repos: Vec<String>,
290    pub package_managers: Option<Vec<String>>,
291    pub native_package_manager: Option<String>,
292    #[serde(default)]
293    pub telemetry_enabled: bool,
294    #[serde(skip_serializing_if = "Option::is_none")]
295    pub registry: Option<String>,
296    #[serde(default)]
297    pub default_registry: Option<Registry>,
298    #[serde(default)]
299    pub added_registries: Vec<Registry>,
300    #[serde(default)]
301    pub git_repos: Vec<String>,
302    #[serde(default)]
303    pub rollback_enabled: bool,
304    #[serde(default)]
305    pub policy: Policy,
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub parallel_jobs: Option<usize>,
308    #[serde(default)]
309    pub protect_db: bool,
310}
311
312#[derive(Debug, Serialize, Deserialize, Clone, Default)]
313pub struct Policy {
314    #[serde(default, skip_serializing_if = "is_false")]
315    pub repos_unoverridable: bool,
316    #[serde(default, skip_serializing_if = "is_false")]
317    pub telemetry_enabled_unoverridable: bool,
318    #[serde(default, skip_serializing_if = "is_false")]
319    pub rollback_enabled_unoverridable: bool,
320    #[serde(default, skip_serializing_if = "is_false")]
321    pub default_registry_unoverridable: bool,
322    #[serde(default, skip_serializing_if = "is_false")]
323    pub added_registries_unoverridable: bool,
324    #[serde(default, skip_serializing_if = "is_false")]
325    pub git_repos_unoverridable: bool,
326    #[serde(default, skip_serializing_if = "is_false")]
327    pub allow_deny_lists_unoverridable: bool,
328    #[serde(default, skip_serializing_if = "is_false")]
329    pub signature_enforcement_unoverridable: bool,
330    #[serde(default, skip_serializing_if = "is_false")]
331    pub protect_db_unoverridable: bool,
332
333    #[serde(default, skip_serializing_if = "Option::is_none")]
334    pub allowed_licenses: Option<Vec<String>>,
335    #[serde(default, skip_serializing_if = "Option::is_none")]
336    pub denied_licenses: Option<Vec<String>>,
337
338    #[serde(default, skip_serializing_if = "Option::is_none")]
339    pub allowed_packages: Option<Vec<String>>,
340    #[serde(default, skip_serializing_if = "Option::is_none")]
341    pub denied_packages: Option<Vec<String>>,
342
343    #[serde(default, skip_serializing_if = "Option::is_none")]
344    pub allowed_repos: Option<Vec<String>>,
345    #[serde(default, skip_serializing_if = "Option::is_none")]
346    pub denied_repos: Option<Vec<String>>,
347
348    #[serde(default, skip_serializing_if = "Option::is_none")]
349    pub signature_enforcement: Option<SignatureEnforcementPolicy>,
350}
351
352#[derive(Debug, Serialize, Deserialize, Clone, Default)]
353pub struct SignatureEnforcementPolicy {
354    #[serde(default)]
355    pub enable: bool,
356    #[serde(default)]
357    pub trusted_keys: Vec<String>,
358}
359
360fn is_false(b: &bool) -> bool {
361    !*b
362}
363
364#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
365pub struct SharableInstallManifest {
366    pub name: String,
367    pub version: String,
368    pub repo: String,
369    pub registry_handle: String,
370    pub scope: Scope,
371    #[serde(default, skip_serializing_if = "Vec::is_empty")]
372    pub chosen_options: Vec<String>,
373    #[serde(default, skip_serializing_if = "Vec::is_empty")]
374    pub chosen_optionals: Vec<String>,
375}
376
377#[derive(Debug, Serialize, Deserialize, Clone)]
378pub struct ZoiLockOld {
379    pub packages: HashMap<String, String>,
380}
381
382#[derive(Debug, Serialize, Deserialize, Clone, Default)]
383pub struct ZoiLock {
384    pub version: String,
385    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
386    pub registries: HashMap<String, String>,
387    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
388    pub packages: HashMap<String, String>,
389    #[serde(flatten)]
390    pub details: HashMap<String, HashMap<String, LockPackageDetail>>,
391}
392
393#[derive(Debug, Serialize, Deserialize, Clone)]
394pub struct LockPackageDetail {
395    pub version: String,
396    #[serde(default, skip_serializing_if = "Option::is_none")]
397    pub sub_package: Option<String>,
398    pub integrity: String,
399    #[serde(default, skip_serializing_if = "Vec::is_empty")]
400    pub dependencies: Vec<String>,
401    #[serde(default, skip_serializing_if = "Vec::is_empty")]
402    pub options_dependencies: Vec<String>,
403    #[serde(default, skip_serializing_if = "Vec::is_empty")]
404    pub optionals_dependencies: Vec<String>,
405}
406
407#[derive(Debug, Serialize, Deserialize, Clone)]
408pub struct Lockfile {
409    pub version: String,
410    pub packages: HashMap<String, LockfilePackage>,
411}
412
413#[derive(Debug, Serialize, Deserialize, Clone)]
414pub struct LockfilePackage {
415    pub name: String,
416    #[serde(default, skip_serializing_if = "Option::is_none")]
417    pub sub_package: Option<String>,
418    pub repo: String,
419    pub registry: String,
420    pub version: String,
421    pub date: String,
422    pub reason: InstallReason,
423    pub scope: Scope,
424    #[serde(default, skip_serializing_if = "Option::is_none")]
425    pub bins: Option<Vec<String>>,
426    #[serde(default, skip_serializing_if = "Option::is_none")]
427    pub conflicts: Option<Vec<String>>,
428    #[serde(default, skip_serializing_if = "Option::is_none")]
429    pub replaces: Option<Vec<String>>,
430    #[serde(default, skip_serializing_if = "Option::is_none")]
431    pub provides: Option<Vec<String>>,
432    #[serde(default, skip_serializing_if = "Option::is_none")]
433    pub backup: Option<Vec<String>>,
434    #[serde(default, skip_serializing_if = "Vec::is_empty")]
435    pub dependencies: Vec<String>,
436    #[serde(default, skip_serializing_if = "Vec::is_empty")]
437    pub chosen_options: Vec<String>,
438    #[serde(default, skip_serializing_if = "Vec::is_empty")]
439    pub chosen_optionals: Vec<String>,
440}
441
442#[derive(Debug, Serialize, Deserialize, Clone)]
443pub struct GitLink {
444    #[serde(rename = "type")]
445    pub link_type: String,
446    pub url: String,
447}
448
449#[derive(Debug, Serialize, Deserialize, Clone)]
450pub struct PkgLink {
451    #[serde(rename = "type")]
452    pub link_type: String,
453    pub url: String,
454    pub pgp: Option<String>,
455    pub hash: Option<String>,
456}
457
458#[derive(Debug, Serialize, Deserialize, Clone)]
459pub struct PgpKey {
460    pub name: String,
461    pub key: String,
462}
463
464#[derive(Debug, Serialize, Deserialize, Clone)]
465pub struct RepoEntry {
466    pub name: String,
467    #[serde(rename = "type")]
468    pub repo_type: String,
469    pub active: bool,
470}
471
472#[derive(Debug, Serialize, Deserialize, Clone)]
473pub struct RepoConfig {
474    pub name: String,
475    pub description: String,
476    pub git: Vec<GitLink>,
477    #[serde(default)]
478    pub pkg: Vec<PkgLink>,
479    #[serde(default)]
480    pub pgp: Vec<PgpKey>,
481    pub repos: Vec<RepoEntry>,
482}