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}