use std::collections::HashMap;
use std::time::Duration;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum BackendType {
Bitwarden,
OnePassword,
Pass,
WindowsCredentialManager,
AWSSecretsManager,
GCPSecretManager,
AzureKeyVault,
}
impl std::fmt::Display for BackendType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Bitwarden => write!(f, "bitwarden"),
Self::OnePassword => write!(f, "1password"),
Self::Pass => write!(f, "pass"),
Self::WindowsCredentialManager => write!(f, "wincred"),
Self::AWSSecretsManager => write!(f, "awssecrets"),
Self::GCPSecretManager => write!(f, "gcpsecrets"),
Self::AzureKeyVault => write!(f, "azurekeyvault"),
}
}
}
#[derive(Debug, Clone)]
pub struct Config {
pub backend: BackendType,
pub store_path: Option<String>,
pub prefix: String,
pub session_file: Option<String>,
pub session_ttl: Duration,
pub options: HashMap<String, String>,
}
impl Default for Config {
fn default() -> Self {
Self {
backend: BackendType::Pass,
store_path: None,
prefix: "dotfiles".to_string(),
session_file: None,
session_ttl: Duration::from_secs(1800), options: HashMap::new(),
}
}
}
impl Config {
pub fn new(backend: BackendType) -> Self {
Self {
backend,
..Default::default()
}
}
pub fn with_prefix(mut self, prefix: impl Into<String>) -> Self {
self.prefix = prefix.into();
self
}
pub fn with_store_path(mut self, path: impl Into<String>) -> Self {
self.store_path = Some(path.into());
self
}
pub fn with_session_file(mut self, path: impl Into<String>) -> Self {
self.session_file = Some(path.into());
self
}
pub fn with_session_ttl(mut self, ttl: Duration) -> Self {
self.session_ttl = ttl;
self
}
pub fn with_option(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.options.insert(key.into(), value.into());
self
}
pub fn get_option(&self, key: &str) -> Option<&String> {
self.options.get(key)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_builder() {
let config = Config::new(BackendType::AWSSecretsManager)
.with_prefix("myapp")
.with_option("region", "us-west-2")
.with_session_ttl(Duration::from_secs(3600));
assert_eq!(config.backend, BackendType::AWSSecretsManager);
assert_eq!(config.prefix, "myapp");
assert_eq!(config.get_option("region"), Some(&"us-west-2".to_string()));
assert_eq!(config.session_ttl, Duration::from_secs(3600));
}
#[test]
fn test_backend_type_display() {
assert_eq!(BackendType::Bitwarden.to_string(), "bitwarden");
assert_eq!(BackendType::Pass.to_string(), "pass");
assert_eq!(BackendType::AWSSecretsManager.to_string(), "awssecrets");
}
#[test]
fn test_default_config() {
let config = Config::default();
assert_eq!(config.backend, BackendType::Pass);
assert_eq!(config.prefix, "dotfiles");
assert_eq!(config.session_ttl, Duration::from_secs(1800));
}
}