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    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}