Files
ostiary/src/config.rs
2026-05-22 11:24:42 +07:00

83 lines
2.2 KiB
Rust

use serde::{Deserialize, Serialize};
use anyhow::Result;
use std::fs;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Config {
pub server_url: String,
pub timeout_sec: u64,
#[serde(default = "default_theme")]
pub theme: Theme,
#[serde(default)]
pub update_api: Option<String>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Theme {
#[serde(default = "default_selected_bg")]
pub selected_bg: String,
}
fn default_selected_bg() -> String {
"blue".to_string()
}
fn default_theme() -> Theme {
Theme {
selected_bg: default_selected_bg(),
}
}
pub fn config_path() -> PathBuf {
// Respect XDG_CONFIG_HOME; fall back to ~/.config on all platforms.
let base = std::env::var("XDG_CONFIG_HOME")
.map(PathBuf::from)
.unwrap_or_else(|_| {
dirs::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".config")
});
base.join(env!("CARGO_PKG_NAME")).join("config.toml")
}
impl Config {
/// Returns true when a config file already exists.
pub fn exists() -> bool {
config_path().exists()
}
/// Load config from disk. Panics-safe: returns error if file is missing or malformed.
pub fn load() -> Result<Self> {
let path = config_path();
let content = fs::read_to_string(&path)?;
Ok(toml::from_str(&content)?)
}
/// Create and persist a new config with the given server URL.
pub fn create_with_url(server_url: &str) -> Result<Self> {
let path = config_path();
let config = Config {
server_url: server_url.to_string(),
timeout_sec: 10,
theme: default_theme(),
update_api: Some("https://git.vainend.com/api/v1/repos/admin/ostiary".to_string()),
};
let contents = format!(
r#"server_url = "{}"
timeout_sec = {}
update_api = "https://git.vainend.com/api/v1/repos/admin/ostiary"
[theme]
selected_bg = "{}"
"#,
config.server_url,
config.timeout_sec,
config.theme.selected_bg,
);
fs::create_dir_all(path.parent().unwrap())?;
fs::write(&path, contents)?;
Ok(config)
}
}