use confy::{get_configuration_file_path, load, store};
use miette::{Context, IntoDiagnostic, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::PathBuf;
use crate::cli::args::ProviderKind;
const APP_NAME: &str = env!("CARGO_PKG_NAME");
const CONFIG_NAME: &str = "config";
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Profile {
pub provider: Option<ProviderKind>,
pub tenant_id: Option<String>,
pub domain: Option<String>,
pub audience: Option<String>,
pub client_id: Option<String>,
pub default_scopes: Option<String>,
}
#[derive(Serialize, Deserialize, Default, Debug)]
pub struct CliConfig {
#[serde(default)]
pub profiles: HashMap<String, Profile>,
}
impl CliConfig {
pub fn load() -> Result<Self> {
let cfg: CliConfig = load(APP_NAME, CONFIG_NAME)
.into_diagnostic()
.wrap_err("Failed to load configuration")?;
Ok(cfg)
}
pub fn save(&self) -> Result<()> {
store(APP_NAME, CONFIG_NAME, self)
.into_diagnostic()
.wrap_err("Failed to save configuration")?;
Ok(())
}
pub fn get_path() -> Result<PathBuf> {
let path = get_configuration_file_path(APP_NAME, CONFIG_NAME)
.into_diagnostic()
.wrap_err("Could not determine config path")?;
Ok(path)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config_is_empty() {
let config = CliConfig::default();
assert!(config.profiles.is_empty());
}
#[test]
fn test_config_serialization_deserialization() {
let mut original_config = CliConfig::default();
original_config.profiles.insert(
"prod".to_string(),
Profile {
provider: Some(ProviderKind::Microsoft),
tenant_id: Some("common".to_string()),
client_id: Some("12345".to_string()),
..Default::default()
},
);
let serialized = serde_json::to_string(&original_config).expect("Should serialize");
assert!(serialized.contains("prod"));
assert!(serialized.contains("Microsoft"));
assert!(serialized.contains("common"));
assert!(serialized.contains("12345"));
let deserialized: CliConfig =
serde_json::from_str(&serialized).expect("Should deserialize");
let prod_profile = deserialized.profiles.get("prod").unwrap();
assert_eq!(prod_profile.tenant_id.as_deref(), Some("common"));
}
}