use std::{fs, path::Path};
use derpscfg::indexmap::IndexMap;
use derpscfg::prelude::*;
use crate::ConfigError;
#[derive(Debug, Derpscfg)]
pub(crate) struct ScfgSend {
pub(crate) remote: Option<String>,
pub(crate) from: Option<String>,
pub(crate) user: Option<String>,
pub(crate) password: Option<String>,
#[scfg(name = "pass-cmd")]
pub(crate) pass_cmd: Option<String>,
}
#[derive(Debug, Derpscfg)]
pub(crate) struct ScfgAccount {
pub(crate) local: Option<String>,
pub(crate) remote: Option<String>,
pub(crate) user: Option<String>,
pub(crate) password: Option<String>,
#[scfg(name = "pass-cmd")]
pub(crate) pass_cmd: Option<String>,
pub(crate) send: Option<ScfgSend>,
}
#[derive(Debug, Derpscfg)]
pub(crate) struct ScfgConfig {
#[scfg(name = "account")]
accounts: IndexMap<String, ScfgAccount>,
}
impl ScfgConfig {
pub(crate) fn for_account(&self, name: Option<&str>) -> Option<(&String, &ScfgAccount)> {
if let Some(name) = name {
self.accounts.get_key_value(name)
} else {
self.accounts.iter().next()
}
}
}
pub(crate) fn load_scfg(doc: &str) -> Result<ScfgConfig, ConfigError> {
let cfg: ScfgConfig = derpscfg::parse(doc)?;
if cfg.accounts.is_empty() {
Err(ConfigError::Error("no accounts found"))
} else {
Ok(cfg)
}
}
pub(crate) fn load_scfg_file<P: AsRef<Path>>(path: P) -> Result<ScfgConfig, ConfigError> {
let contents = fs::read_to_string(path)?;
load_scfg(&contents)
}
#[cfg(test)]
mod tests {
use super::*;
static TEST: &str = "
account example {
local '/home/test/.maildir'
remote 'mx.example.com'
user 'johndoe'
password 'hunter1'
}";
#[test]
fn test_load() {
let cfg = load_scfg(TEST).unwrap();
assert_eq!(cfg.accounts.len(), 1);
}
#[test]
fn test_load_empty() {
let cfg = load_scfg("");
assert!(matches!(cfg, Err(ConfigError::Error(_))))
}
static TEST_DUP: &str = "
account example {
local '/home/test/.maildir'
remote 'mx.example.com'
user 'johndoe'
password 'hunter1'
}
account example {
local '/home/test/.maildir'
remote 'mx.example.com'
user 'johndoe'
password 'hunter1'
}";
#[test]
fn test_load_dup() {
let cfg = load_scfg(TEST_DUP);
assert!(matches!(
cfg,
Err(ConfigError::ScfgError(derpscfg::Error::DuplicateKey(_)))
));
}
}