use anyhow::{Context, Result};
use log::{debug, info, trace};
use serde::Deserialize;
use std::{collections::HashMap, env, fs, path::PathBuf};
use toml;
use crate::config::DeserializedAccountConfig;
pub const DEFAULT_PAGE_SIZE: usize = 10;
pub const DEFAULT_SIG_DELIM: &str = "-- \n";
pub const DEFAULT_INBOX_FOLDER: &str = "INBOX";
pub const DEFAULT_SENT_FOLDER: &str = "Sent";
pub const DEFAULT_DRAFT_FOLDER: &str = "Drafts";
#[derive(Debug, Default, Clone, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct DeserializedConfig {
pub name: String,
pub downloads_dir: Option<PathBuf>,
pub signature: Option<String>,
pub signature_delimiter: Option<String>,
pub default_page_size: Option<usize>,
pub notify_cmd: Option<String>,
pub notify_query: Option<String>,
pub watch_cmds: Option<Vec<String>>,
#[serde(flatten)]
pub accounts: HashMap<String, DeserializedAccountConfig>,
}
impl DeserializedConfig {
pub fn from_opt_path(path: Option<&str>) -> Result<Self> {
info!("begin: try to parse config from path");
debug!("path: {:?}", path);
let path = path.map(|s| s.into()).unwrap_or(Self::path()?);
let content = fs::read_to_string(path).context("cannot read config file")?;
let config = toml::from_str(&content).context("cannot parse config file")?;
info!("end: try to parse config from path");
trace!("config: {:?}", config);
Ok(config)
}
fn path_from_xdg() -> Result<PathBuf> {
let path =
env::var("XDG_CONFIG_HOME").context("cannot find \"XDG_CONFIG_HOME\" env var")?;
let path = PathBuf::from(path).join("himalaya").join("config.toml");
Ok(path)
}
fn path_from_xdg_alt() -> Result<PathBuf> {
let home_var = if cfg!(target_family = "windows") {
"USERPROFILE"
} else {
"HOME"
};
let path = env::var(home_var).context(format!("cannot find {:?} env var", home_var))?;
let path = PathBuf::from(path)
.join(".config")
.join("himalaya")
.join("config.toml");
Ok(path)
}
fn path_from_home() -> Result<PathBuf> {
let home_var = if cfg!(target_family = "windows") {
"USERPROFILE"
} else {
"HOME"
};
let path = env::var(home_var).context(format!("cannot find {:?} env var", home_var))?;
let path = PathBuf::from(path).join(".himalayarc");
Ok(path)
}
pub fn path() -> Result<PathBuf> {
Self::path_from_xdg()
.or_else(|_| Self::path_from_xdg_alt())
.or_else(|_| Self::path_from_home())
.context("cannot find config path")
}
}