use std::path::PathBuf;
use directories::ProjectDirs;
use crate::error::{Error, Result};
const APP: &str = "ks";
const IDENTITY_FILE: &str = "identity.age";
const STORE_DIR: &str = "store";
const RECIPIENTS_FILE: &str = ".age-recipients";
pub const ENV_DIR: &str = "KS_DIR";
pub const ENV_STORE_DIR: &str = "KS_STORE_DIR";
pub const ENV_IDENTITY: &str = "KS_IDENTITY";
#[derive(Debug, Clone)]
pub struct Config {
pub identity_path: PathBuf,
pub store_dir: PathBuf,
}
impl Config {
pub fn load() -> Result<Self> {
let data_dir = match env_path(ENV_DIR) {
Some(dir) => dir,
None => ProjectDirs::from("", "", APP)
.ok_or(Error::NoUserDir)?
.data_dir()
.to_path_buf(),
};
Ok(Self {
identity_path: env_path(ENV_IDENTITY).unwrap_or_else(|| data_dir.join(IDENTITY_FILE)),
store_dir: env_path(ENV_STORE_DIR).unwrap_or_else(|| data_dir.join(STORE_DIR)),
})
}
#[must_use]
pub fn recipients_path(&self) -> PathBuf {
self.store_dir.join(RECIPIENTS_FILE)
}
}
fn env_path(name: &str) -> Option<PathBuf> {
match std::env::var(name) {
Ok(raw) if !raw.is_empty() => Some(PathBuf::from(raw)),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn recipients_path_is_under_store() {
let cfg = Config {
identity_path: PathBuf::from("/tmp/ks/identity.age"),
store_dir: PathBuf::from("/tmp/ks/store"),
};
assert_eq!(
cfg.recipients_path(),
PathBuf::from("/tmp/ks/store/.age-recipients")
);
}
}