use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::path::Path;
use tokio::fs;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Profile {
pub aad: Option<String>,
pub key_b64: Option<String>,
pub url: Option<String>,
pub url_rev: Option<String>,
pub url_b64: Option<String>,
pub output: Option<String>,
}
impl Default for Profile {
fn default() -> Self {
Self {
aad: None,
key_b64: None,
url: None,
url_rev: None,
url_b64: None,
output: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub default: Option<Profile>,
#[serde(default)]
pub profile: std::collections::HashMap<String, Profile>,
}
impl Config {
pub async fn from_toml_file<P: AsRef<Path>>(path: P) -> Result<Self> {
let content = fs::read_to_string(path.as_ref())
.await
.context("failed to read config file")?;
toml::from_str(&content).context("failed to parse TOML config")
}
pub async fn from_json_file<P: AsRef<Path>>(path: P) -> Result<Self> {
let content = fs::read_to_string(path.as_ref())
.await
.context("failed to read config file")?;
serde_json::from_str(&content).context("failed to parse JSON config")
}
pub fn get_profile(&self, name: Option<&str>) -> Option<Profile> {
match name {
Some(profile_name) => self.profile.get(profile_name).cloned(),
None => self.default.clone(),
}
}
pub fn merge_with_cli(
mut profile: Profile,
key_b64: Option<String>,
url: Option<String>,
url_rev: Option<String>,
url_b64: Option<String>,
aad: Option<String>,
output: Option<String>,
) -> Profile {
if let Some(k) = key_b64 {
profile.key_b64 = Some(k);
}
if let Some(u) = url {
profile.url = Some(u);
}
if let Some(ur) = url_rev {
profile.url_rev = Some(ur);
}
if let Some(ub) = url_b64 {
profile.url_b64 = Some(ub);
}
if let Some(a) = aad {
profile.aad = Some(a);
}
if let Some(o) = output {
profile.output = Some(o);
}
profile
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_profile_merge() {
let profile = Profile {
aad: Some("aad-1".to_string()),
key_b64: Some("key1".to_string()),
url: Some("https://example.com".to_string()),
url_rev: None,
url_b64: None,
output: None,
};
let merged = Config::merge_with_cli(
profile,
None,
Some("https://override.com".to_string()),
None,
None,
None,
None,
);
assert_eq!(merged.url.unwrap(), "https://override.com");
assert_eq!(merged.aad.unwrap(), "aad-1");
}
}