use anyhow::Result;
use directories::ProjectDirs;
use serde::Deserialize;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Default, Clone)]
pub struct Config {
pub prometheus_url: Option<String>,
pub refresh_rate: Option<u64>,
pub time_range: Option<String>,
pub step: Option<String>,
pub theme: Option<String>,
pub grafana_json: Option<PathBuf>,
pub threshold_marker: Option<String>,
pub autogrid: Option<bool>,
pub autogrid_color: Option<String>,
pub vars: Option<HashMap<String, String>>,
}
impl Config {
pub fn load(cli_path: Option<PathBuf>) -> Result<Self> {
let config_path = cli_path
.map(|p| expand_path(&p))
.or_else(Self::get_config_path);
if let Some(path) = config_path {
if path.exists() {
let content = fs::read_to_string(path)?;
let config: Config = toml::from_str(&content)?;
return Ok(config);
}
}
Ok(Config::default())
}
fn get_config_path() -> Option<PathBuf> {
if let Some(base_dirs) = ProjectDirs::from("", "", "grafatui") {
let config_path = base_dirs.config_dir().join("config.toml");
if config_path.exists() {
return Some(config_path);
}
let config_path = base_dirs.config_dir().join("grafatui.toml");
if config_path.exists() {
return Some(config_path);
}
}
let cwd_path = PathBuf::from("./grafatui.toml");
if cwd_path.exists() {
return Some(cwd_path.to_path_buf());
}
None
}
}
pub fn expand_path(path: &std::path::Path) -> PathBuf {
let path_str = path.to_string_lossy();
if path_str.starts_with("~") {
if let Some(dirs) = directories::UserDirs::new() {
let home = dirs.home_dir();
if path_str == "~" {
return home.to_path_buf();
}
if path_str.starts_with("~/") || path_str.starts_with("~\\") {
return home.join(&path_str[2..]);
}
}
}
path.to_path_buf()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_deserialization() {
let toml_str = r#"
prometheus_url = "http://localhost:9090"
refresh_rate = 5000
theme = "dracula"
autogrid = false
autogrid_color = "gray"
"#;
let config: Config = toml::from_str(toml_str).unwrap();
assert_eq!(
config.prometheus_url,
Some("http://localhost:9090".to_string())
);
assert_eq!(config.refresh_rate, Some(5000));
assert_eq!(config.theme, Some("dracula".to_string()));
assert_eq!(config.autogrid, Some(false));
assert_eq!(config.autogrid_color, Some("gray".to_string()));
}
#[test]
fn test_expand_path() {
if let Some(dirs) = directories::UserDirs::new() {
let home = dirs.home_dir();
let p = PathBuf::from("~");
assert_eq!(expand_path(&p), home);
let p = PathBuf::from("~/foo/bar.json");
assert_eq!(expand_path(&p), home.join("foo/bar.json"));
let p = PathBuf::from("./local.json");
assert_eq!(expand_path(&p), p);
let p = PathBuf::from("/etc/config");
assert_eq!(expand_path(&p), p);
}
}
}