1use anyhow::Result;
7use serde::Deserialize;
8use serde_json::from_slice;
9use std::{fmt::Display, fs::read, path::PathBuf};
10use typed_builder::TypedBuilder;
11use versions::Versioning;
12
13use crate::Internal;
14
15#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
16pub struct IPathObject {
18 pub id: isize,
20 pub priority: isize,
22 #[builder(setter(into))]
23 pub value: String,
25 pub enabled: bool,
27 #[serde(rename = "isWritable")]
28 #[builder(default, setter(strip_option))]
29 pub writable: Option<bool>,
31}
32
33#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
34pub struct RepoPath {
36 #[builder(setter(into))]
37 pub value: String,
39 pub enabled: bool,
41 pub priority: isize,
43 pub id: isize,
45}
46
47#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
48#[builder(field_defaults(setter(into)))]
49pub struct Rectangle {
51 pub x: isize,
53 pub y: isize,
55 pub width: isize,
57 pub height: isize,
59}
60
61#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
62#[serde(rename_all = "lowercase")]
63pub enum ProxySettingTypes {
65 None,
67 Env,
69 Manual,
71}
72
73#[derive(Deserialize, Clone, Debug, PartialEq, Eq)]
74pub enum InstallationPreference {
76 RepoOrder,
78 LegacyStyle,
80 NewStyle,
82}
83
84#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
85#[builder(field_defaults(default, setter(strip_option)))]
86pub struct Settings {
89 #[builder(setter(into))]
90 pub archives: Option<Vec<RepoPath>>,
93 #[serde(rename = "cacheTimeout")]
94 pub cache_timeout: Option<isize>,
96 #[serde(rename = "installPath")]
97 pub install_path: Option<IPathObject>,
99 #[serde(rename = "readOnlyInstallationPaths")]
100 #[builder(setter(into))]
101 pub read_only_installation_paths: Option<Vec<IPathObject>>,
104 #[serde(rename = "cfgVersion")]
105 pub cfg_version: Option<isize>,
107 #[serde(rename = "guiBounds")]
108 pub gui_bounds: Option<Rectangle>,
110 #[serde(rename = "guiMaximized")]
111 pub gui_maximized: Option<bool>,
113 #[serde(rename = "powershellPath")]
114 pub powershell_path: Option<PathBuf>,
116 #[serde(rename = "tempDirectory")]
117 pub temp_directory: Option<PathBuf>,
119 #[serde(rename = "multiUser")]
120 pub multi_user: Option<bool>,
122 #[serde(rename = "projectsDefault")]
123 #[builder(setter(into))]
124 pub projects_default: Option<String>,
126 #[serde(rename = "enableRemoteManifests")]
127 pub enable_remote_manifests: Option<bool>,
129 #[serde(rename = "manifestRepos")]
130 #[builder(setter(into))]
131 pub manifest_repos: Option<Vec<IPathObject>>,
134 #[serde(rename = "projects")]
135 #[builder(setter(into))]
136 pub projects: Option<Vec<IPathObject>>,
138 #[serde(rename = "manifests")]
139 #[builder(setter(into))]
140 pub manifests: Option<Vec<IPathObject>>,
142 #[serde(rename = "keyStore")]
143 #[builder(setter(into))]
144 pub key_store: Option<Vec<IPathObject>>,
147 #[serde(rename = "ignoreLegacyPlatformRepoDeprecation")]
148 pub ignore_legacy_platform_repo_deprecation: Option<bool>,
150 #[serde(rename = "proxySettingsToUse")]
151 pub proxy_settings_to_use: Option<ProxySettingTypes>,
154 #[serde(rename = "httpsProxy")]
155 #[builder(setter(into))]
156 pub https_proxy: Option<String>,
159 #[serde(rename = "httpProxy")]
160 #[builder(setter(into))]
161 pub http_proxy: Option<String>,
164 #[serde(rename = "noProxy")]
165 #[builder(setter(into))]
166 pub no_proxy: Option<String>,
168 #[serde(rename = "AuthenticationConfig")]
169 #[builder(setter(into))]
170 pub authentication_config: Option<String>,
173 #[serde(rename = "logfile")]
174 #[builder(setter(into))]
175 pub logfile: Option<String>,
177 #[serde(rename = "preferPackageType")]
178 pub prefer_package_type: Option<InstallationPreference>,
180}
181
182impl Settings {
183 pub fn get() -> Result<Self> {
185 Ok(from_slice(&read(Internal::cfg_file_path()?)?)?)
186 }
187}
188
189#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
190pub struct InstalledPackage {
192 #[serde(rename = "pkgNumber")]
193 pub package_number: isize,
195 pub version: String,
197 #[builder(setter(into))]
198 pub name: String,
200 #[builder(default, setter(into))]
201 pub paths: Vec<PathBuf>,
203}
204
205impl InstalledPackage {
206 pub fn version(&self) -> Versioning {
208 Versioning::new(&self.version).expect("Failed to parse installed package version")
209 }
210}
211
212#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
213pub struct AvailablePackage {
215 #[serde(rename = "pkgNumber")]
216 pub package_number: isize,
218 pub version: String,
220 #[builder(setter(into))]
221 pub name: String,
223 pub installed: bool,
225}
226
227impl AvailablePackage {
228 pub fn version(&self) -> Versioning {
230 Versioning::new(&self.version).expect("Failed to parse available package version")
231 }
232}
233
234#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
235#[builder(field_defaults(default, setter(strip_option, into)))]
236pub struct Packages {
238 #[serde(rename = "installedPackages")]
239 pub installed_packages: Option<Vec<InstalledPackage>>,
241 #[serde(rename = "availablePackages")]
242 pub available_packages: Option<Vec<AvailablePackage>>,
244}
245
246impl Packages {
247 pub fn sort(&mut self) {
249 if let Some(installed_packages) = self.installed_packages.as_mut() {
250 installed_packages.sort_by_key(|b| std::cmp::Reverse(b.version()))
251 }
252 }
253}
254
255#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq, Hash)]
256pub struct ProjectPackage {
258 #[serde(rename = "pkgNumber")]
259 pub package_number: isize,
261 #[builder(setter(into))]
262 pub version: String,
264}
265
266impl Display for ProjectPackage {
267 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268 write!(f, "{}-{}", self.package_number, self.version)
269 }
270}
271
272impl ProjectPackage {
273 pub fn version(&self) -> Versioning {
275 Versioning::new(&self.version).expect("Failed to parse project package version")
276 }
277}
278
279#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
280pub struct Project {
282 #[builder(setter(into))]
283 pub name: String,
285 #[builder(setter(into))]
286 pub description: String,
288 pub path: PathBuf,
290 #[builder(default, setter(into))]
291 pub packages: Vec<ProjectPackage>,
293}
294
295#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
296#[builder(field_defaults(default, setter(into)))]
297pub struct Projects {
299 pub projects: Vec<Project>,
301}
302
303#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
304pub struct Platform {
306 #[builder(setter(into))]
307 pub name: String,
309 #[builder(setter(into))]
310 pub group: String,
312 #[builder(setter(into))]
313 pub path: String,
315 pub remote: bool,
317}
318
319#[derive(TypedBuilder, Deserialize, Clone, Debug, PartialEq, Eq)]
320#[builder(field_defaults(default, setter(into)))]
321pub struct Platforms {
323 pub platforms: Vec<Platform>,
325}