@@ -33,6 +33,7 @@ pub enum Error {
33
33
Io ( std:: io:: Error ) ,
34
34
NoConfigDirectory ,
35
35
Notify ( notify:: Error ) ,
36
+ NotFound ,
36
37
Ron ( ron:: Error ) ,
37
38
RonSpanned ( ron:: error:: SpannedError ) ,
38
39
GetKey ( String , std:: io:: Error ) ,
@@ -46,6 +47,7 @@ impl fmt::Display for Error {
46
47
Self :: Io ( err) => err. fmt ( f) ,
47
48
Self :: NoConfigDirectory => write ! ( f, "cosmic config directory not found" ) ,
48
49
Self :: Notify ( err) => err. fmt ( f) ,
50
+ Self :: NotFound => write ! ( f, "cosmic config key not configured" ) ,
49
51
Self :: Ron ( err) => err. fmt ( f) ,
50
52
Self :: RonSpanned ( err) => err. fmt ( f) ,
51
53
Self :: GetKey ( key, err) => write ! ( f, "failed to get key '{}': {}" , key, err) ,
@@ -55,6 +57,15 @@ impl fmt::Display for Error {
55
57
56
58
impl std:: error:: Error for Error { }
57
59
60
+ impl Error {
61
+ /// Whether the reason for the missing config is caused by an error.
62
+ ///
63
+ /// Useful for determining if it is appropriate to log as an error.
64
+ pub fn is_err ( & self ) -> bool {
65
+ matches ! ( self , Self :: NoConfigDirectory | Self :: NotFound )
66
+ }
67
+ }
68
+
58
69
impl From < atomicwrites:: Error < std:: io:: Error > > for Error {
59
70
fn from ( f : atomicwrites:: Error < std:: io:: Error > ) -> Self {
60
71
Self :: AtomicWrites ( f)
@@ -87,7 +98,15 @@ impl From<ron::error::SpannedError> for Error {
87
98
88
99
pub trait ConfigGet {
89
100
/// Get a configuration value
101
+ ///
102
+ /// Fallback to the system default if a local user override is not defined.
90
103
fn get < T : DeserializeOwned > ( & self , key : & str ) -> Result < T , Error > ;
104
+
105
+ /// Get a locally-defined configuration value from the user's local config.
106
+ fn get_local < T : DeserializeOwned > ( & self , key : & str ) -> Result < T , Error > ;
107
+
108
+ /// Get the system-defined default configuration value.
109
+ fn get_system_default < T : DeserializeOwned > ( & self , key : & str ) -> Result < T , Error > ;
91
110
}
92
111
93
112
pub trait ConfigSet {
@@ -216,7 +235,7 @@ impl Config {
216
235
}
217
236
218
237
// Start a transaction (to set multiple configs at the same time)
219
- pub fn transaction < ' a > ( & ' a self ) -> ConfigTransaction < ' a > {
238
+ pub fn transaction ( & self ) -> ConfigTransaction {
220
239
ConfigTransaction {
221
240
config : self ,
222
241
updates : Mutex :: new ( Vec :: new ( ) ) ,
@@ -288,6 +307,7 @@ impl Config {
288
307
Ok ( system_path. join ( sanitize_name ( key) ?) )
289
308
}
290
309
310
+ /// Get the path of the key in the user's local config directory.
291
311
fn key_path ( & self , key : & str ) -> Result < PathBuf , Error > {
292
312
let Some ( user_path) = self . user_path . as_ref ( ) else {
293
313
return Err ( Error :: NoConfigDirectory ) ;
@@ -300,22 +320,34 @@ impl Config {
300
320
impl ConfigGet for Config {
301
321
//TODO: check for transaction
302
322
fn get < T : DeserializeOwned > ( & self , key : & str ) -> Result < T , Error > {
323
+ match self . get_local ( key) {
324
+ Ok ( value) => Ok ( value) ,
325
+ Err ( Error :: NotFound ) => self . get_system_default ( key) ,
326
+ Err ( why) => Err ( why) ,
327
+ }
328
+ }
329
+
330
+ fn get_local < T : DeserializeOwned > ( & self , key : & str ) -> Result < T , Error > {
303
331
// If key path exists
304
- let key_path = self . key_path ( key) ;
305
- let data = match key_path {
306
- Ok ( key_path) if key_path. is_file ( ) => {
332
+ match self . key_path ( key) ? {
333
+ key_path if key_path. is_file ( ) => {
307
334
// Load user override
308
- fs:: read_to_string ( key_path) . map_err ( |err| Error :: GetKey ( key. to_string ( ) , err) ) ?
309
- }
310
- _ => {
311
- // Load system default
312
- let default_path = self . default_path ( key) ?;
313
- fs:: read_to_string ( default_path)
314
- . map_err ( |err| Error :: GetKey ( key. to_string ( ) , err) ) ?
335
+ let data = fs:: read_to_string ( key_path)
336
+ . map_err ( |err| Error :: GetKey ( key. to_string ( ) , err) ) ?;
337
+
338
+ Ok ( ron:: from_str ( & data) ?)
315
339
}
316
- } ;
317
- let t = ron:: from_str ( & data) ?;
318
- Ok ( t)
340
+
341
+ _ => Err ( Error :: NotFound ) ,
342
+ }
343
+ }
344
+
345
+ fn get_system_default < T : DeserializeOwned > ( & self , key : & str ) -> Result < T , Error > {
346
+ // Load system default
347
+ let default_path = self . default_path ( key) ?;
348
+ let data =
349
+ fs:: read_to_string ( default_path) . map_err ( |err| Error :: GetKey ( key. to_string ( ) , err) ) ?;
350
+ Ok ( ron:: from_str ( & data) ?)
319
351
}
320
352
}
321
353
0 commit comments