winbrew_database\config/
registry.rs1use tracing_subscriber::EnvFilter;
2
3use super::error::ConfigValidationError;
4
5pub type Validator = fn(&str) -> std::result::Result<(), ConfigValidationError>;
6
7pub struct KeyDef {
8 pub key: &'static str,
9 pub validator: Option<Validator>,
10}
11
12pub static KEYS: &[KeyDef] = &[
13 KeyDef {
14 key: "core.log_level",
15 validator: Some(|value| {
16 EnvFilter::try_new(value).map_err(|err| ConfigValidationError::InvalidLogLevel {
17 value: value.to_string(),
18 reason: err.to_string(),
19 })?;
20 Ok(())
21 }),
22 },
23 KeyDef {
24 key: "core.file_log_level",
25 validator: Some(|value| {
26 EnvFilter::try_new(value).map_err(|err| {
27 ConfigValidationError::InvalidFileLogLevel {
28 value: value.to_string(),
29 reason: err.to_string(),
30 }
31 })?;
32 Ok(())
33 }),
34 },
35 KeyDef {
36 key: "core.auto_update",
37 validator: Some(validate_bool),
38 },
39 KeyDef {
40 key: "core.confirm_remove",
41 validator: Some(validate_bool),
42 },
43 KeyDef {
44 key: "core.default_yes",
45 validator: Some(validate_bool),
46 },
47 KeyDef {
48 key: "core.color",
49 validator: Some(validate_bool),
50 },
51 KeyDef {
52 key: "paths.root",
53 validator: None,
54 },
55 KeyDef {
56 key: "paths.packages",
57 validator: None,
58 },
59 KeyDef {
60 key: "paths.data",
61 validator: None,
62 },
63 KeyDef {
64 key: "paths.logs",
65 validator: None,
66 },
67 KeyDef {
68 key: "paths.cache",
69 validator: None,
70 },
71];
72
73pub fn find(key: &str) -> Option<&'static KeyDef> {
74 KEYS.iter().find(|def| def.key == key)
75}
76
77pub fn suggest_key(key: &str) -> Option<&'static str> {
78 let key = key.trim();
79
80 if key.is_empty() {
81 return None;
82 }
83
84 if let Some(exact) = KEYS.iter().find(|def| def.key.eq_ignore_ascii_case(key)) {
85 return Some(exact.key);
86 }
87
88 if key.contains('.') {
89 return None;
90 }
91
92 for section in ["core", "paths"] {
93 let candidate = format!("{section}.{key}");
94
95 if let Some(exact) = KEYS
96 .iter()
97 .find(|def| def.key.eq_ignore_ascii_case(&candidate))
98 {
99 return Some(exact.key);
100 }
101 }
102
103 None
104}
105
106fn validate_bool(value: &str) -> std::result::Result<(), ConfigValidationError> {
107 parse_bool_value(value)
108 .map(|_| ())
109 .ok_or_else(|| ConfigValidationError::ExpectedBoolean {
110 value: value.to_string(),
111 })
112}
113
114pub(super) fn parse_bool_value(value: &str) -> Option<bool> {
115 match value {
116 "true" | "1" | "yes" | "on" => Some(true),
117 "false" | "0" | "no" | "off" => Some(false),
118 _ => None,
119 }
120}