use serde::{Deserialize, Serialize};
use super::hetzner::HetznerConfig;
use super::lxd::LxdConfig;
use super::Provider;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "provider")]
pub enum ProviderConfig {
#[serde(rename = "lxd")]
Lxd(LxdConfig),
#[serde(rename = "hetzner")]
Hetzner(HetznerConfig),
}
impl ProviderConfig {
#[must_use]
pub fn provider(&self) -> Provider {
match self {
Self::Lxd(_) => Provider::Lxd,
Self::Hetzner(_) => Provider::Hetzner,
}
}
#[must_use]
pub fn provider_name(&self) -> &'static str {
self.provider().as_str()
}
#[must_use]
pub fn provider_display_name(&self) -> &'static str {
match self {
Self::Lxd(_) => "LXD",
Self::Hetzner(_) => "Hetzner Cloud",
}
}
#[must_use]
pub fn as_lxd(&self) -> Option<&LxdConfig> {
match self {
Self::Lxd(config) => Some(config),
Self::Hetzner(_) => None,
}
}
#[must_use]
pub fn as_hetzner(&self) -> Option<&HetznerConfig> {
match self {
Self::Lxd(_) => None,
Self::Hetzner(config) => Some(config),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::domain::ProfileName;
fn create_lxd_config() -> ProviderConfig {
ProviderConfig::Lxd(LxdConfig {
profile_name: ProfileName::new("torrust-profile").unwrap(),
})
}
fn create_hetzner_config() -> ProviderConfig {
use crate::shared::ApiToken;
ProviderConfig::Hetzner(HetznerConfig {
api_token: ApiToken::from("test-token"),
server_type: "cx22".to_string(),
location: "nbg1".to_string(),
image: "ubuntu-24.04".to_string(),
})
}
#[test]
fn it_should_return_lxd_provider_when_lxd_config_queried() {
let config = create_lxd_config();
assert_eq!(config.provider(), Provider::Lxd);
assert_eq!(config.provider_name(), "lxd");
}
#[test]
fn it_should_return_hetzner_provider_when_hetzner_config_queried() {
let config = create_hetzner_config();
assert_eq!(config.provider(), Provider::Hetzner);
assert_eq!(config.provider_name(), "hetzner");
}
#[test]
fn it_should_return_some_lxd_config_when_as_lxd_called_on_lxd_variant() {
let config = create_lxd_config();
assert!(config.as_lxd().is_some());
assert!(config.as_hetzner().is_none());
}
#[test]
fn it_should_return_some_hetzner_config_when_as_hetzner_called_on_hetzner_variant() {
let config = create_hetzner_config();
assert!(config.as_hetzner().is_some());
assert!(config.as_lxd().is_none());
}
#[test]
fn it_should_serialize_lxd_config_to_json_with_provider_tag() {
let config = create_lxd_config();
let json = serde_json::to_string(&config).unwrap();
assert!(json.contains("\"provider\":\"lxd\""));
assert!(json.contains("\"profile_name\":\"torrust-profile\""));
}
#[test]
fn it_should_serialize_hetzner_config_to_json_with_provider_tag() {
let config = create_hetzner_config();
let json = serde_json::to_string(&config).unwrap();
assert!(json.contains("\"provider\":\"hetzner\""));
assert!(json.contains("\"api_token\":\"test-token\""));
assert!(json.contains("\"server_type\":\"cx22\""));
assert!(json.contains("\"location\":\"nbg1\""));
}
#[test]
fn it_should_deserialize_lxd_config_from_json_with_provider_tag() {
let json = r#"{"provider":"lxd","profile_name":"torrust-profile"}"#;
let config: ProviderConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.provider(), Provider::Lxd);
assert_eq!(
config.as_lxd().unwrap().profile_name.as_str(),
"torrust-profile"
);
}
#[test]
fn it_should_deserialize_hetzner_config_from_json_with_provider_tag() {
let json = r#"{"provider":"hetzner","api_token":"token","server_type":"cx22","location":"nbg1","image":"ubuntu-24.04"}"#;
let config: ProviderConfig = serde_json::from_str(json).unwrap();
assert_eq!(config.provider(), Provider::Hetzner);
let hetzner = config.as_hetzner().unwrap();
assert_eq!(hetzner.api_token.expose_secret(), "token");
assert_eq!(hetzner.server_type, "cx22");
assert_eq!(hetzner.location, "nbg1");
assert_eq!(hetzner.image, "ubuntu-24.04");
}
#[test]
fn it_should_be_cloneable_when_cloned() {
let config = create_lxd_config();
let cloned = config.clone();
assert_eq!(config, cloned);
}
#[test]
fn it_should_implement_debug_trait_when_formatted() {
let config = create_lxd_config();
let debug = format!("{config:?}");
assert!(debug.contains("Lxd"));
assert!(debug.contains("profile_name"));
}
}