use anyhow::{Context, Result};
use serde::Deserialize;
use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Debug, Deserialize, Clone)]
pub struct Config {
#[serde(default = "default_idle_timeout")]
pub idle_timeout: u64,
#[serde(default)]
pub server: HashMap<String, ServerConfig>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct ServerConfig {
pub command: String,
#[serde(default)]
pub args: Vec<String>,
#[serde(default)]
pub initialization_options: Option<serde_json::Value>,
}
fn default_idle_timeout() -> u64 {
300
}
impl Config {
pub fn load(explicit_file: Option<PathBuf>) -> Result<Self> {
let mut builder = config::Config::builder();
builder = builder
.set_default("idle_timeout", 300)?;
if let Some(config_dir) = dirs::config_dir() {
let config_path = config_dir.join("catenary").join("config.toml");
if config_path.exists() {
builder = builder.add_source(config::File::from(config_path));
}
}
if let Some(path) = explicit_file {
builder = builder.add_source(config::File::from(path));
}
builder = builder.add_source(config::Environment::with_prefix("CATENARY"));
let config = builder
.build()
.context("Failed to build configuration")?;
config.try_deserialize().context("Failed to deserialize configuration")
}
}