@@ -33,6 +33,7 @@ pub enum Error {
3333 Io ( std:: io:: Error ) ,
3434 NoConfigDirectory ,
3535 Notify ( notify:: Error ) ,
36+ NotFound ,
3637 Ron ( ron:: Error ) ,
3738 RonSpanned ( ron:: error:: SpannedError ) ,
3839 GetKey ( String , std:: io:: Error ) ,
@@ -46,6 +47,7 @@ impl fmt::Display for Error {
4647 Self :: Io ( err) => err. fmt ( f) ,
4748 Self :: NoConfigDirectory => write ! ( f, "cosmic config directory not found" ) ,
4849 Self :: Notify ( err) => err. fmt ( f) ,
50+ Self :: NotFound => write ! ( f, "cosmic config key not configured" ) ,
4951 Self :: Ron ( err) => err. fmt ( f) ,
5052 Self :: RonSpanned ( err) => err. fmt ( f) ,
5153 Self :: GetKey ( key, err) => write ! ( f, "failed to get key '{}': {}" , key, err) ,
@@ -55,6 +57,15 @@ impl fmt::Display for Error {
5557
5658impl std:: error:: Error for Error { }
5759
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+
5869impl From < atomicwrites:: Error < std:: io:: Error > > for Error {
5970 fn from ( f : atomicwrites:: Error < std:: io:: Error > ) -> Self {
6071 Self :: AtomicWrites ( f)
@@ -87,7 +98,15 @@ impl From<ron::error::SpannedError> for Error {
8798
8899pub trait ConfigGet {
89100 /// Get a configuration value
101+ ///
102+ /// Fallback to the system default if a local user override is not defined.
90103 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 > ;
91110}
92111
93112pub trait ConfigSet {
@@ -216,7 +235,7 @@ impl Config {
216235 }
217236
218237 // 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 {
220239 ConfigTransaction {
221240 config : self ,
222241 updates : Mutex :: new ( Vec :: new ( ) ) ,
@@ -288,6 +307,7 @@ impl Config {
288307 Ok ( system_path. join ( sanitize_name ( key) ?) )
289308 }
290309
310+ /// Get the path of the key in the user's local config directory.
291311 fn key_path ( & self , key : & str ) -> Result < PathBuf , Error > {
292312 let Some ( user_path) = self . user_path . as_ref ( ) else {
293313 return Err ( Error :: NoConfigDirectory ) ;
@@ -300,22 +320,34 @@ impl Config {
300320impl ConfigGet for Config {
301321 //TODO: check for transaction
302322 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 > {
303331 // 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 ( ) => {
307334 // 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) ?)
315339 }
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) ?)
319351 }
320352}
321353
0 commit comments