use std::time::Duration;
use serde::{Deserialize, Serialize};
use super::types::DurationStr;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ClusterConfig {
#[serde(default = "default_cluster_name")]
pub name: String,
#[serde(default)]
pub discovery: DiscoveryMethod,
#[serde(default = "default_heartbeat_interval")]
pub heartbeat_interval: DurationStr,
#[serde(default = "default_dead_threshold")]
pub dead_threshold: DurationStr,
#[serde(default)]
pub seed_nodes: Vec<String>,
pub dns_name: Option<String>,
}
impl Default for ClusterConfig {
fn default() -> Self {
Self {
name: default_cluster_name(),
discovery: DiscoveryMethod::default(),
heartbeat_interval: default_heartbeat_interval(),
dead_threshold: default_dead_threshold(),
seed_nodes: Vec::new(),
dns_name: None,
}
}
}
impl ClusterConfig {
pub fn with_dns_name(mut self, dns_name: String) -> Self {
self.dns_name = Some(dns_name);
self
}
}
fn default_cluster_name() -> String {
"default".to_string()
}
fn default_heartbeat_interval() -> DurationStr {
DurationStr::new(Duration::from_secs(5))
}
fn default_dead_threshold() -> DurationStr {
DurationStr::new(Duration::from_secs(15))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "lowercase")]
pub enum DiscoveryMethod {
#[default]
Postgres,
Dns,
Kubernetes,
Static,
}
#[cfg(test)]
#[allow(clippy::unwrap_used, clippy::indexing_slicing)]
mod tests {
use super::*;
#[test]
fn test_default_cluster_config() {
let config = ClusterConfig::default();
assert_eq!(config.name, "default");
assert_eq!(config.discovery, DiscoveryMethod::Postgres);
assert_eq!(config.heartbeat_interval.as_secs(), 5);
}
#[test]
fn test_parse_cluster_config() {
let toml = r#"
name = "production"
discovery = "kubernetes"
heartbeat_interval = "10s"
"#;
let config: ClusterConfig = toml::from_str(toml).unwrap();
assert_eq!(config.name, "production");
assert_eq!(config.discovery, DiscoveryMethod::Kubernetes);
}
}