feat: Trying to load several config paths

- Config::load now returns Option<Self> instead of Self
- Updated README to contain new possible config paths
This commit is contained in:
Alexey 2026-04-06 11:18:50 +03:00
commit f00b850b37
3 changed files with 50 additions and 11 deletions

View file

@ -49,7 +49,13 @@ $ ./aliveline
## Configuration ## Configuration
Aliveline tries to find config at: Aliveline tries to find config at:
- `$XDG_CONFIG_DIR/aliveline/config.toml` - `$ALIVELINE_CONFIG`
- `$XDG_CONFIG_HOME/aliveline/config.toml`
- `$XDG_CONFIG_HOME/.aliveline`
- `$HOME/.config/aliveline/config.toml`
- `$HOME/.config/.aliveline`
- `$HOME/.aliveline/config.toml`
- `$HOME/.aliveline`
- `./config.toml` (relative to working directory) - `./config.toml` (relative to working directory)
If config isn't found, Aliveline uses default values defined in [config.toml](https://2ndbeam.ru/git/2ndbeam/aliveline/src/branch/master/config.toml). If config isn't found, Aliveline uses default values defined in [config.toml](https://2ndbeam.ru/git/2ndbeam/aliveline/src/branch/master/config.toml).

View file

@ -20,14 +20,16 @@ impl Default for Colors {
} }
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)] #[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(default)]
pub struct Config { pub struct Config {
/// directory, where config is located /// directory, where config is located
#[serde(skip)] #[serde(skip)]
pub conf_path: PathBuf, pub conf_path: PathBuf,
pub log_path: PathBuf, pub log_path: PathBuf,
#[serde(default)]
pub colors: Colors, pub colors: Colors,
#[serde(default)]
pub event_colors: Vec<u32>, pub event_colors: Vec<u32>,
#[serde(default)]
pub text_colors: Vec<u32>, pub text_colors: Vec<u32>,
} }
@ -90,13 +92,13 @@ impl Config {
} }
} }
pub fn load(path: PathBuf) -> Self { pub fn load(path: PathBuf) -> Option<Self> {
if let Ok(toml_string) = std::fs::read_to_string(path.clone()) { if let Ok(toml_string) = std::fs::read_to_string(path.clone()) {
if let Ok(mut conf) = toml::from_str::<Config>(&toml_string) { if let Ok(mut conf) = toml::from_str::<Config>(&toml_string) {
conf.conf_path = path.parent().unwrap().into(); conf.conf_path = path.parent().unwrap().into();
return conf; return Some(conf);
} }
} }
Config::new(path) None
} }
} }

View file

@ -4,16 +4,47 @@ use std::{hash::{DefaultHasher, Hash, Hasher}, path::PathBuf};
pub mod config; pub mod config;
pub mod log; pub mod log;
pub fn load_config() -> Config { fn try_config_path(var: &'static str, path: &[&'static str]) -> Option<Config> {
if let Ok(path_str) = std::env::var("XDG_CONFIG_HOME") { match std::env::var(var) {
let mut path = PathBuf::from(path_str); Ok(path_start) => {
path.push("aliveline"); let mut pathbuf = PathBuf::from(path_start);
path.push("config.toml"); for entry in path.iter() {
return Config::load(path); pathbuf.push(entry);
}
Config::load(pathbuf)
},
Err(_) => None,
} }
Config::new(PathBuf::from("./config.toml"))
} }
/// This function tries to load config from several places (in order):
/// - $ALIVELINE_CONFIG
/// - $XDG_CONFIG_HOME/aliveline/config.toml
/// - $XDG_CONFIG_HOME/.aliveline
/// - $HOME/.config/aliveline/config.toml
/// - $HOME/.config/.aliveline
/// - $HOME/.aliveline
/// as a last resort it defaults to current working directory (./config.toml)
pub fn load_config() -> Config {
let places = [
("ALIVELINE_CONFIG", vec![]),
("XDG_CONFIG_HOME", vec!["aliveline", "config.toml"]),
("XDG_CONFIG_HOME", vec![".aliveline"]),
("HOME", vec![".config", "aliveline", "config.toml"]),
("HOME", vec![".config", ".aliveline"]),
("HOME", vec![".aliveline", "config.toml"]),
("HOME", vec![".aliveline"]),
];
for (place_var, place) in places {
if let Some(conf) = try_config_path(place_var, place.as_slice()) {
println!("Found config at ${place_var} / {place:?}");
return conf;
}
println!("Config not found at ${place_var} / {place:?}");
}
println!("Using last resort config path ./config.toml");
Config::new(PathBuf::from("./config.toml"))
}
/// Get random-like color id in range 0..16 by computing string hash /// Get random-like color id in range 0..16 by computing string hash
pub fn color_id_from_name(name: String) -> i32 { pub fn color_id_from_name(name: String) -> i32 {
let mut s = DefaultHasher::new(); let mut s = DefaultHasher::new();