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)]
93 pub conflicts: Option<Vec<String>>,
94 #[serde(default)]
95 pub tags: Vec<String>,
96 #[serde(default)]
97 pub extension: Option<ExtensionInfo>,
98 #[serde(default)]
99 pub rollback: Option<bool>,
100 #[serde(default)]
101 pub updates: Option<Vec<UpdateInfo>>,
102 #[serde(default)]
103 pub hooks: Option<Hooks>,
104}
105
106#[derive(Debug, Serialize, Deserialize, Clone)]
107#[serde(untagged)]
108pub enum PlatformOrStringVec {
109 StringVec(Vec<String>),
110 Platform(HashMap<String, Vec<String>>),
111}
112
113#[derive(Debug, Serialize, Deserialize, Clone, Default)]
114pub struct Hooks {
115 #[serde(default, skip_serializing_if = "Option::is_none")]
116 pub pre_install: Option<PlatformOrStringVec>,
117 #[serde(default, skip_serializing_if = "Option::is_none")]
118 pub post_install: Option<PlatformOrStringVec>,
119 #[serde(default, skip_serializing_if = "Option::is_none")]
120 pub pre_upgrade: Option<PlatformOrStringVec>,
121 #[serde(default, skip_serializing_if = "Option::is_none")]
122 pub post_upgrade: Option<PlatformOrStringVec>,
123 #[serde(default, skip_serializing_if = "Option::is_none")]
124 pub pre_remove: Option<PlatformOrStringVec>,
125 #[serde(default, skip_serializing_if = "Option::is_none")]
126 pub post_remove: Option<PlatformOrStringVec>,
127}
128
129#[derive(Debug, Serialize, Deserialize, Clone)]
130#[allow(dead_code)]
131pub struct Maintainer {
132 pub name: String,
133 pub email: String,
134 pub website: Option<String>,
135}
136
137#[derive(Debug, Serialize, Deserialize, Clone)]
138#[allow(dead_code)]
139pub struct Author {
140 pub name: String,
141 pub email: Option<String>,
142 pub website: Option<String>,
143}
144
145#[derive(Debug, Serialize, Deserialize, Clone)]
146#[allow(dead_code)]
147pub struct DependencyOptionGroup {
148 pub name: String,
149 pub desc: String,
150 #[serde(default)]
151 pub all: bool,
152 pub depends: Vec<String>,
153}
154
155#[derive(Debug, Serialize, Deserialize, Clone)]
156#[serde(untagged)]
157pub enum DependencyGroup {
158 Simple(Vec<String>),
159 Complex(ComplexDependencyGroup),
160}
161
162impl DependencyGroup {
163 pub fn get_required_simple(&self) -> Vec<String> {
164 match self {
165 DependencyGroup::Simple(deps) => deps.clone(),
166 DependencyGroup::Complex(group) => group.required.clone(),
167 }
168 }
169
170 pub fn get_required_options(&self) -> Vec<DependencyOptionGroup> {
171 match self {
172 DependencyGroup::Simple(_) => Vec::new(),
173 DependencyGroup::Complex(group) => group.options.clone(),
174 }
175 }
176
177 pub fn get_optional(&self) -> &Vec<String> {
178 match self {
179 DependencyGroup::Simple(_) => {
180 static EMPTY_VEC: Vec<String> = Vec::new();
181 &EMPTY_VEC
182 }
183 DependencyGroup::Complex(group) => &group.optional,
184 }
185 }
186}
187
188#[derive(Debug, Serialize, Deserialize, Clone, Default)]
189pub struct ComplexDependencyGroup {
190 #[serde(default)]
191 pub required: Vec<String>,
192 #[serde(default)]
193 pub options: Vec<DependencyOptionGroup>,
194 #[serde(default)]
195 pub optional: Vec<String>,
196 #[serde(default, skip_serializing_if = "Option::is_none")]
197 pub sub_packages: Option<HashMap<String, DependencyGroup>>,
198}
199
200#[derive(Debug, Serialize, Deserialize, Clone)]
201pub struct Dependencies {
202 #[serde(default)]
203 pub runtime: Option<DependencyGroup>,
204 #[serde(default)]
205 pub build: Option<DependencyGroup>,
206}
207
208#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
209pub enum InstallReason {
210 Direct,
211 Dependency { parent: String },
212}
213
214#[derive(Debug, Serialize, Deserialize, Clone)]
215pub struct InstallManifest {
216 pub name: String,
217 pub version: String,
218 #[serde(default, skip_serializing_if = "Option::is_none")]
219 pub sub_package: Option<String>,
220 pub repo: String,
221 pub registry_handle: String,
222 pub package_type: PackageType,
223 pub reason: InstallReason,
224 pub scope: Scope,
225 pub bins: Option<Vec<String>>,
226 pub conflicts: Option<Vec<String>>,
227 #[serde(default)]
228 pub installed_dependencies: Vec<String>,
229 #[serde(default)]
230 pub chosen_options: Vec<String>,
231 #[serde(default)]
232 pub chosen_optionals: Vec<String>,
233 #[serde(default)]
234 pub install_method: Option<String>,
235 #[serde(default)]
236 pub installed_files: Vec<String>,
237}
238
239#[derive(Debug, Serialize, Deserialize, Clone)]
240#[serde(rename_all = "camelCase")]
241pub enum TransactionOperation {
242 Install {
243 manifest: Box<InstallManifest>,
244 },
245 Uninstall {
246 manifest: Box<InstallManifest>,
247 },
248 Upgrade {
249 old_manifest: Box<InstallManifest>,
250 new_manifest: Box<InstallManifest>,
251 },
252}
253
254#[derive(Debug, Serialize, Deserialize, Clone)]
255pub struct Transaction {
256 pub id: String,
257 pub start_time: String,
258 pub operations: Vec<TransactionOperation>,
259}
260
261#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
262pub struct Registry {
263 pub handle: String,
264 pub url: String,
265}
266
267#[derive(Debug, Serialize, Deserialize, Default, Clone)]
268pub struct Config {
269 pub repos: Vec<String>,
270 pub package_managers: Option<Vec<String>>,
271 pub native_package_manager: Option<String>,
272 #[serde(default)]
273 pub telemetry_enabled: bool,
274 #[serde(skip_serializing_if = "Option::is_none")]
275 pub registry: Option<String>,
276 #[serde(default)]
277 pub default_registry: Option<Registry>,
278 #[serde(default)]
279 pub added_registries: Vec<Registry>,
280 #[serde(default)]
281 pub git_repos: Vec<String>,
282 #[serde(default)]
283 pub rollback_enabled: bool,
284 #[serde(default)]
285 pub policy: Policy,
286 #[serde(skip_serializing_if = "Option::is_none")]
287 pub parallel_jobs: Option<usize>,
288}
289
290#[derive(Debug, Serialize, Deserialize, Clone, Default)]
291pub struct Policy {
292 #[serde(default, skip_serializing_if = "is_false")]
293 pub repos_unoverridable: bool,
294 #[serde(default, skip_serializing_if = "is_false")]
295 pub telemetry_enabled_unoverridable: bool,
296 #[serde(default, skip_serializing_if = "is_false")]
297 pub rollback_enabled_unoverridable: bool,
298 #[serde(default, skip_serializing_if = "is_false")]
299 pub default_registry_unoverridable: bool,
300 #[serde(default, skip_serializing_if = "is_false")]
301 pub added_registries_unoverridable: bool,
302 #[serde(default, skip_serializing_if = "is_false")]
303 pub git_repos_unoverridable: bool,
304 #[serde(default, skip_serializing_if = "is_false")]
305 pub allow_deny_lists_unoverridable: bool,
306 #[serde(default, skip_serializing_if = "is_false")]
307 pub signature_enforcement_unoverridable: bool,
308
309 #[serde(default, skip_serializing_if = "Option::is_none")]
310 pub allowed_licenses: Option<Vec<String>>,
311 #[serde(default, skip_serializing_if = "Option::is_none")]
312 pub denied_licenses: Option<Vec<String>>,
313
314 #[serde(default, skip_serializing_if = "Option::is_none")]
315 pub allowed_packages: Option<Vec<String>>,
316 #[serde(default, skip_serializing_if = "Option::is_none")]
317 pub denied_packages: Option<Vec<String>>,
318
319 #[serde(default, skip_serializing_if = "Option::is_none")]
320 pub allowed_repos: Option<Vec<String>>,
321 #[serde(default, skip_serializing_if = "Option::is_none")]
322 pub denied_repos: Option<Vec<String>>,
323
324 #[serde(default, skip_serializing_if = "Option::is_none")]
325 pub signature_enforcement: Option<SignatureEnforcementPolicy>,
326}
327
328#[derive(Debug, Serialize, Deserialize, Clone, Default)]
329pub struct SignatureEnforcementPolicy {
330 #[serde(default)]
331 pub enable: bool,
332 #[serde(default)]
333 pub trusted_keys: Vec<String>,
334}
335
336fn is_false(b: &bool) -> bool {
337 !*b
338}
339
340#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
341pub struct SharableInstallManifest {
342 pub name: String,
343 pub version: String,
344 pub repo: String,
345 pub registry_handle: String,
346 pub scope: Scope,
347 #[serde(default, skip_serializing_if = "Vec::is_empty")]
348 pub chosen_options: Vec<String>,
349 #[serde(default, skip_serializing_if = "Vec::is_empty")]
350 pub chosen_optionals: Vec<String>,
351}
352
353#[derive(Debug, Serialize, Deserialize, Clone)]
354pub struct ZoiLockOld {
355 pub packages: HashMap<String, String>,
356}
357
358#[derive(Debug, Serialize, Deserialize, Clone, Default)]
359pub struct ZoiLock {
360 pub version: String,
361 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
362 pub registries: HashMap<String, String>,
363 #[serde(default, skip_serializing_if = "HashMap::is_empty")]
364 pub packages: HashMap<String, String>,
365 #[serde(flatten)]
366 pub details: HashMap<String, HashMap<String, LockPackageDetail>>,
367}
368
369#[derive(Debug, Serialize, Deserialize, Clone)]
370pub struct LockPackageDetail {
371 pub version: String,
372 #[serde(default, skip_serializing_if = "Option::is_none")]
373 pub sub_package: Option<String>,
374 pub integrity: String,
375 #[serde(default, skip_serializing_if = "Vec::is_empty")]
376 pub dependencies: Vec<String>,
377 #[serde(default, skip_serializing_if = "Vec::is_empty")]
378 pub options_dependencies: Vec<String>,
379 #[serde(default, skip_serializing_if = "Vec::is_empty")]
380 pub optionals_dependencies: Vec<String>,
381}
382
383#[derive(Debug, Serialize, Deserialize, Clone)]
384pub struct Lockfile {
385 pub version: String,
386 pub packages: HashMap<String, LockfilePackage>,
387}
388
389#[derive(Debug, Serialize, Deserialize, Clone)]
390pub struct LockfilePackage {
391 pub name: String,
392 #[serde(default, skip_serializing_if = "Option::is_none")]
393 pub sub_package: Option<String>,
394 pub repo: String,
395 pub registry: String,
396 pub version: String,
397 pub date: String,
398 pub reason: InstallReason,
399 pub scope: Scope,
400 #[serde(default, skip_serializing_if = "Option::is_none")]
401 pub bins: Option<Vec<String>>,
402 #[serde(default, skip_serializing_if = "Option::is_none")]
403 pub conflicts: Option<Vec<String>>,
404 #[serde(default, skip_serializing_if = "Vec::is_empty")]
405 pub dependencies: Vec<String>,
406 #[serde(default, skip_serializing_if = "Vec::is_empty")]
407 pub chosen_options: Vec<String>,
408 #[serde(default, skip_serializing_if = "Vec::is_empty")]
409 pub chosen_optionals: Vec<String>,
410}
411
412#[derive(Debug, Serialize, Deserialize, Clone)]
413pub struct GitLink {
414 #[serde(rename = "type")]
415 pub link_type: String,
416 pub url: String,
417}
418
419#[derive(Debug, Serialize, Deserialize, Clone)]
420pub struct PkgLink {
421 #[serde(rename = "type")]
422 pub link_type: String,
423 pub url: String,
424 pub pgp: Option<String>,
425 pub hash: Option<String>,
426}
427
428#[derive(Debug, Serialize, Deserialize, Clone)]
429pub struct PgpKey {
430 pub name: String,
431 pub key: String,
432}
433
434#[derive(Debug, Serialize, Deserialize, Clone)]
435pub struct RepoEntry {
436 pub name: String,
437 #[serde(rename = "type")]
438 pub repo_type: String,
439 pub active: bool,
440}
441
442#[derive(Debug, Serialize, Deserialize, Clone)]
443pub struct RepoConfig {
444 pub name: String,
445 pub description: String,
446 pub git: Vec<GitLink>,
447 #[serde(default)]
448 pub pkg: Vec<PkgLink>,
449 #[serde(default)]
450 pub pgp: Vec<PgpKey>,
451 pub repos: Vec<RepoEntry>,
452}