winbrew_database\config/
types.rs1use std::collections::HashMap;
2use std::path::PathBuf;
3
4use super::keys::env_override;
5use super::registry;
6use crate::core::env::LOCALAPPDATA;
7pub use crate::models::shared::config::{ConfigSection, ConfigValueSource as ConfigSource};
8use serde::{Deserialize, Serialize};
9
10const FALLBACK_ROOT_PATH: &str = r"C:\winbrew";
11
12#[derive(Debug, Clone, Default, Serialize, Deserialize)]
13pub struct Config {
14 #[serde(default)]
15 pub core: CoreConfig,
16
17 #[serde(default)]
18 pub paths: PathsConfig,
19
20 #[serde(skip, default)]
21 pub env: ConfigEnv,
22
23 #[serde(skip, default)]
24 pub(crate) config_root: Option<PathBuf>,
25}
26
27#[derive(Debug, Clone, Default)]
28pub struct ConfigEnv {
29 values: HashMap<String, String>,
30}
31
32impl ConfigEnv {
33 pub fn capture() -> Self {
34 let mut values = HashMap::new();
35
36 for def in registry::KEYS {
37 if let Some(value) = env_override(def.key) {
38 values.insert(def.key.to_string(), value);
39 }
40 }
41
42 Self { values }
43 }
44
45 pub fn value(&self, key: &str) -> Option<&str> {
46 self.values.get(key).map(String::as_str)
47 }
48
49 pub fn root_override(&self) -> Option<&str> {
50 self.value("paths.root")
51 }
52}
53
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct CoreConfig {
56 #[serde(default = "default_log_level")]
57 pub log_level: String,
58
59 #[serde(default = "default_file_log_level")]
60 pub file_log_level: String,
61
62 #[serde(default = "default_true")]
63 pub auto_update: bool,
64
65 #[serde(default = "default_true")]
66 pub confirm_remove: bool,
67
68 #[serde(default)]
69 pub default_yes: bool,
70
71 #[serde(default = "default_true")]
72 pub color: bool,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct PathsConfig {
77 #[serde(default = "default_root_path")]
78 pub root: String,
79
80 #[serde(default = "default_packages_path")]
81 pub packages: String,
82
83 #[serde(default = "default_data_path")]
84 pub data: String,
85
86 #[serde(default = "default_logs_path")]
87 pub logs: String,
88
89 #[serde(default = "default_cache_path")]
90 pub cache: String,
91}
92
93impl Default for CoreConfig {
94 fn default() -> Self {
95 Self {
96 log_level: default_log_level(),
97 file_log_level: default_file_log_level(),
98 auto_update: default_true(),
99 confirm_remove: default_true(),
100 default_yes: false,
101 color: default_true(),
102 }
103 }
104}
105
106impl Default for PathsConfig {
107 fn default() -> Self {
108 Self {
109 root: default_root_path(),
110 packages: default_packages_path(),
111 data: default_data_path(),
112 logs: default_logs_path(),
113 cache: default_cache_path(),
114 }
115 }
116}
117
118fn default_true() -> bool {
120 true
121}
122
123fn default_log_level() -> String {
124 "info".to_string()
125}
126
127fn default_file_log_level() -> String {
128 "debug,winbrew::core=trace".to_string()
129}
130
131pub fn default_root_path() -> String {
132 std::env::var(LOCALAPPDATA)
133 .map(|local_app_data| {
134 PathBuf::from(local_app_data)
135 .join("winbrew")
136 .to_string_lossy()
137 .into_owned()
138 })
139 .unwrap_or_else(|_| FALLBACK_ROOT_PATH.to_string())
140}
141
142fn default_packages_path() -> String {
145 "${root}\\packages".to_string()
146}
147
148fn default_data_path() -> String {
149 "${root}\\data".to_string()
150}
151
152fn default_logs_path() -> String {
153 "${root}\\data\\logs".to_string()
154}
155
156fn default_cache_path() -> String {
157 "${root}\\data\\cache".to_string()
158}