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 RepoAdd { add: String },
47 Project { add: String },
48 Pgp { name: String, key: String },
49}
50
51#[derive(Debug, Serialize, Deserialize, Clone)]
52pub struct ExtensionInfo {
53 #[serde(rename = "type")]
54 pub extension_type: String,
55 pub changes: Vec<ExtensionChange>,
56}
57
58#[derive(Debug, Serialize, Deserialize, Clone)]
59#[allow(dead_code)]
60pub struct Package {
61 pub name: String,
62 pub repo: String,
63 pub version: Option<String>,
64 pub versions: Option<HashMap<String, String>>,
65 pub description: String,
66 pub website: Option<String>,
67 #[serde(default)]
68 pub readme: Option<String>,
69 #[serde(default)]
70 pub man: Option<String>,
71 #[serde(default)]
72 pub git: String,
73 pub maintainer: Maintainer,
74 pub author: Option<Author>,
75 #[serde(default)]
76 pub license: String,
77 #[serde(default)]
78 pub types: Vec<String>,
79 pub dependencies: Option<Dependencies>,
80 #[serde(rename = "type", default)]
81 pub package_type: PackageType,
82 pub alt: Option<String>,
83 #[serde(default)]
84 pub scope: Scope,
85 #[serde(default)]
86 pub bins: Option<Vec<String>>,
87 #[serde(default)]
88 pub conflicts: Option<Vec<String>>,
89 #[serde(default)]
90 pub tags: Vec<String>,
91 #[serde(default)]
92 pub extension: Option<ExtensionInfo>,
93 #[serde(default)]
94 pub rollback: Option<bool>,
95 #[serde(default)]
96 pub updates: Option<Vec<UpdateInfo>>,
97 #[serde(default)]
98 pub hooks: Option<Hooks>,
99}
100
101#[derive(Debug, Serialize, Deserialize, Clone)]
102#[serde(untagged)]
103pub enum PlatformOrStringVec {
104 StringVec(Vec<String>),
105 Platform(HashMap<String, Vec<String>>),
106}
107
108#[derive(Debug, Serialize, Deserialize, Clone, Default)]
109pub struct Hooks {
110 #[serde(default, skip_serializing_if = "Option::is_none")]
111 pub pre_install: Option<PlatformOrStringVec>,
112 #[serde(default, skip_serializing_if = "Option::is_none")]
113 pub post_install: Option<PlatformOrStringVec>,
114 #[serde(default, skip_serializing_if = "Option::is_none")]
115 pub pre_upgrade: Option<PlatformOrStringVec>,
116 #[serde(default, skip_serializing_if = "Option::is_none")]
117 pub post_upgrade: Option<PlatformOrStringVec>,
118 #[serde(default, skip_serializing_if = "Option::is_none")]
119 pub pre_remove: Option<PlatformOrStringVec>,
120 #[serde(default, skip_serializing_if = "Option::is_none")]
121 pub post_remove: Option<PlatformOrStringVec>,
122}
123
124#[derive(Debug, Serialize, Deserialize, Clone)]
125#[allow(dead_code)]
126pub struct Maintainer {
127 pub name: String,
128 pub email: String,
129 pub website: Option<String>,
130}
131
132#[derive(Debug, Serialize, Deserialize, Clone)]
133#[allow(dead_code)]
134pub struct Author {
135 pub name: String,
136 pub email: Option<String>,
137 pub website: Option<String>,
138}
139
140#[derive(Debug, Serialize, Deserialize, Clone)]
141#[allow(dead_code)]
142pub struct DependencyOptionGroup {
143 pub name: String,
144 pub desc: String,
145 #[serde(default)]
146 pub all: bool,
147 pub depends: Vec<String>,
148}
149
150#[derive(Debug, Serialize, Deserialize, Clone)]
151#[serde(untagged)]
152pub enum DependencyGroup {
153 Simple(Vec<String>),
154 Complex(ComplexDependencyGroup),
155}
156
157impl DependencyGroup {
158 pub fn get_required_simple(&self) -> Vec<String> {
159 match self {
160 DependencyGroup::Simple(deps) => deps.clone(),
161 DependencyGroup::Complex(group) => group.required.clone(),
162 }
163 }
164
165 pub fn get_required_options(&self) -> Vec<DependencyOptionGroup> {
166 match self {
167 DependencyGroup::Simple(_) => Vec::new(),
168 DependencyGroup::Complex(group) => group.options.clone(),
169 }
170 }
171
172 pub fn get_optional(&self) -> &Vec<String> {
173 match self {
174 DependencyGroup::Simple(_) => {
175 static EMPTY_VEC: Vec<String> = Vec::new();
176 &EMPTY_VEC
177 }
178 DependencyGroup::Complex(group) => &group.optional,
179 }
180 }
181}
182
183#[derive(Debug, Serialize, Deserialize, Clone, Default)]
184pub struct ComplexDependencyGroup {
185 #[serde(default)]
186 pub required: Vec<String>,
187 #[serde(default)]
188 pub options: Vec<DependencyOptionGroup>,
189 #[serde(default)]
190 pub optional: Vec<String>,
191}
192
193#[derive(Debug, Serialize, Deserialize, Clone)]
194pub struct Dependencies {
195 #[serde(default)]
196 pub runtime: Option<DependencyGroup>,
197 #[serde(default)]
198 pub build: Option<DependencyGroup>,
199}
200
201#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
202pub enum InstallReason {
203 Direct,
204 Dependency { parent: String },
205}
206
207#[derive(Debug, Serialize, Deserialize, Clone)]
208pub struct InstallManifest {
209 pub name: String,
210 pub version: String,
211 pub repo: String,
212 pub registry_handle: String,
213 pub package_type: PackageType,
214 pub reason: InstallReason,
215 pub scope: Scope,
216 pub bins: Option<Vec<String>>,
217 pub conflicts: Option<Vec<String>>,
218 #[serde(default)]
219 pub installed_dependencies: Vec<String>,
220 #[serde(default)]
221 pub chosen_options: Vec<String>,
222 #[serde(default)]
223 pub chosen_optionals: Vec<String>,
224 #[serde(default)]
225 pub install_method: Option<String>,
226 #[serde(default)]
227 pub installed_files: Vec<String>,
228}
229
230#[derive(Debug, Serialize, Deserialize, Clone)]
231#[serde(rename_all = "camelCase")]
232pub enum TransactionOperation {
233 Install {
234 manifest: Box<InstallManifest>,
235 },
236 Uninstall {
237 manifest: Box<InstallManifest>,
238 },
239 Upgrade {
240 old_manifest: Box<InstallManifest>,
241 new_manifest: Box<InstallManifest>,
242 },
243}
244
245#[derive(Debug, Serialize, Deserialize, Clone)]
246pub struct Transaction {
247 pub id: String,
248 pub start_time: String,
249 pub operations: Vec<TransactionOperation>,
250}
251
252#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
253pub struct Registry {
254 pub handle: String,
255 pub url: String,
256}
257
258#[derive(Debug, Serialize, Deserialize, Default, Clone)]
259pub struct Config {
260 pub repos: Vec<String>,
261 pub package_managers: Option<Vec<String>>,
262 pub native_package_manager: Option<String>,
263 #[serde(default)]
264 pub telemetry_enabled: bool,
265 #[serde(skip_serializing_if = "Option::is_none")]
266 pub registry: Option<String>,
267 #[serde(default)]
268 pub default_registry: Option<Registry>,
269 #[serde(default)]
270 pub added_registries: Vec<Registry>,
271 #[serde(default)]
272 pub git_repos: Vec<String>,
273 #[serde(default)]
274 pub rollback_enabled: bool,
275 #[serde(default)]
276 pub policy: Policy,
277 #[serde(skip_serializing_if = "Option::is_none")]
278 pub parallel_jobs: Option<usize>,
279}
280
281#[derive(Debug, Serialize, Deserialize, Clone, Default)]
282pub struct Policy {
283 #[serde(default, skip_serializing_if = "is_false")]
284 pub repos_unoverridable: bool,
285 #[serde(default, skip_serializing_if = "is_false")]
286 pub telemetry_enabled_unoverridable: bool,
287 #[serde(default, skip_serializing_if = "is_false")]
288 pub rollback_enabled_unoverridable: bool,
289 #[serde(default, skip_serializing_if = "is_false")]
290 pub default_registry_unoverridable: bool,
291 #[serde(default, skip_serializing_if = "is_false")]
292 pub added_registries_unoverridable: bool,
293 #[serde(default, skip_serializing_if = "is_false")]
294 pub git_repos_unoverridable: bool,
295}
296
297fn is_false(b: &bool) -> bool {
298 !*b
299}
300
301#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
302pub struct SharableInstallManifest {
303 pub name: String,
304 pub version: String,
305 pub repo: String,
306 pub registry_handle: String,
307 pub scope: Scope,
308 #[serde(default, skip_serializing_if = "Vec::is_empty")]
309 pub chosen_options: Vec<String>,
310 #[serde(default, skip_serializing_if = "Vec::is_empty")]
311 pub chosen_optionals: Vec<String>,
312}
313
314#[derive(Debug, Serialize, Deserialize, Clone)]
315pub struct ZoiLock {
316 pub packages: HashMap<String, String>,
317}
318
319#[derive(Debug, Serialize, Deserialize, Clone)]
320pub struct Lockfile {
321 pub version: String,
322 pub packages: HashMap<String, LockfilePackage>,
323}
324
325#[derive(Debug, Serialize, Deserialize, Clone)]
326pub struct LockfilePackage {
327 pub name: String,
328 pub repo: String,
329 pub registry: String,
330 pub version: String,
331 pub date: String,
332 pub reason: InstallReason,
333 pub scope: Scope,
334 #[serde(default, skip_serializing_if = "Option::is_none")]
335 pub bins: Option<Vec<String>>,
336 #[serde(default, skip_serializing_if = "Option::is_none")]
337 pub conflicts: Option<Vec<String>>,
338 #[serde(default, skip_serializing_if = "Vec::is_empty")]
339 pub dependencies: Vec<String>,
340 #[serde(default, skip_serializing_if = "Vec::is_empty")]
341 pub chosen_options: Vec<String>,
342 #[serde(default, skip_serializing_if = "Vec::is_empty")]
343 pub chosen_optionals: Vec<String>,
344}
345
346#[derive(Debug, Serialize, Deserialize, Clone)]
347pub struct GitLink {
348 #[serde(rename = "type")]
349 pub link_type: String,
350 pub url: String,
351}
352
353#[derive(Debug, Serialize, Deserialize, Clone)]
354pub struct PkgLink {
355 #[serde(rename = "type")]
356 pub link_type: String,
357 pub url: String,
358 pub pgp: Option<String>,
359 pub hash: Option<String>,
360}
361
362#[derive(Debug, Serialize, Deserialize, Clone)]
363pub struct PgpKey {
364 pub name: String,
365 pub key: String,
366}
367
368#[derive(Debug, Serialize, Deserialize, Clone)]
369pub struct RepoEntry {
370 pub name: String,
371 #[serde(rename = "type")]
372 pub repo_type: String,
373 pub active: bool,
374}
375
376#[derive(Debug, Serialize, Deserialize, Clone)]
377pub struct RepoConfig {
378 pub name: String,
379 pub description: String,
380 pub git: Vec<GitLink>,
381 #[serde(default)]
382 pub pkg: Vec<PkgLink>,
383 #[serde(default)]
384 pub pgp: Vec<PgpKey>,
385 pub repos: Vec<RepoEntry>,
386}