use std::{env, ffi::OsString, path::PathBuf};
const APP_DIR: &str = "concord";
const CONFIG_FILE: &str = "config.toml";
const KEYMAP_FILE: &str = "keymap.toml";
const THEME_FILE: &str = "theme.toml";
const CREDENTIAL_FILE: &str = "credentials.toml";
const DISCORD_BROWSER_FILE: &str = "discord-browser.toml";
const DISCORD_COOKIE_FILE: &str = "discord-cookies.json";
const LOG_FILE: &str = "concord.log";
const STATE_FILE: &str = "state.toml";
pub fn app_dir() -> Option<PathBuf> {
Some(config_base_dir()?.join(APP_DIR))
}
pub fn state_dir() -> Option<PathBuf> {
Some(state_base_dir()?.join(APP_DIR))
}
pub fn config_file() -> Option<PathBuf> {
Some(app_dir()?.join(CONFIG_FILE))
}
pub fn keymap_file() -> Option<PathBuf> {
Some(app_dir()?.join(KEYMAP_FILE))
}
pub fn theme_file() -> Option<PathBuf> {
Some(app_dir()?.join(THEME_FILE))
}
pub fn credential_file() -> Option<PathBuf> {
Some(state_dir()?.join(CREDENTIAL_FILE))
}
pub(crate) fn discord_browser_file() -> Option<PathBuf> {
Some(state_dir()?.join(DISCORD_BROWSER_FILE))
}
pub(crate) fn discord_cookie_file() -> Option<PathBuf> {
Some(state_dir()?.join(DISCORD_COOKIE_FILE))
}
pub fn state_file() -> Option<PathBuf> {
Some(state_dir()?.join(STATE_FILE))
}
pub fn log_file() -> Option<PathBuf> {
Some(app_dir()?.join(LOG_FILE))
}
pub fn download_dir() -> Option<PathBuf> {
dirs::download_dir().or_else(|| Some(dirs::home_dir()?.join("Downloads")))
}
fn config_base_dir() -> Option<PathBuf> {
absolute_env_path(env::var_os("XDG_CONFIG_HOME")).or_else(dirs::config_dir)
}
fn state_base_dir() -> Option<PathBuf> {
absolute_env_path(env::var_os("XDG_STATE_HOME"))
.or_else(|| Some(dirs::home_dir()?.join(".local").join("state")))
}
fn absolute_env_path(value: Option<OsString>) -> Option<PathBuf> {
value.map(PathBuf::from).filter(|path| path.is_absolute())
}
#[cfg(test)]
mod tests {
use super::absolute_env_path;
#[test]
fn absolute_env_path_accepts_only_absolute_paths() {
let path = std::env::temp_dir().join("concord-xdg-config-home");
for (value, expected) in [
(Some(path.clone().into()), Some(path)),
(Some("relative/path".into()), None),
(None, None),
] {
assert_eq!(absolute_env_path(value), expected);
}
}
}