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}