use figment::Figment;
use figment::providers::Env;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ServiceConfig {
pub name: String,
pub environment: String,
pub host: String,
pub port: u16,
pub debug: bool,
pub log_level: String,
}
impl Default for ServiceConfig {
fn default() -> Self {
Self {
name: "sunbeam-g2v".to_string(),
environment: "development".to_string(),
host: "0.0.0.0".to_string(),
port: 8080,
debug: false,
log_level: "info".to_string(),
}
}
}
impl ServiceConfig {
pub fn load() -> Result<Self, figment::Error> {
let config: Self = Figment::new()
.merge(Env::raw())
.extract()?;
Ok(config)
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct DatabaseConfig {
pub url: String,
pub max_connections: u32,
pub connect_timeout: u64,
}
impl Default for DatabaseConfig {
fn default() -> Self {
Self {
url: "postgres://localhost:5432/sunbeam".to_string(),
max_connections: 10,
connect_timeout: 30,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct NatsConfig {
pub url: String,
pub jetstream: bool,
pub lease_duration: u64,
}
impl Default for NatsConfig {
fn default() -> Self {
Self {
url: "nats://localhost:4222".to_string(),
jetstream: true,
lease_duration: 30,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AuthConfig {
pub jwt_secret: String,
pub token_expiry: u64,
}
impl Default for AuthConfig {
fn default() -> Self {
Self {
jwt_secret: "change-me".to_string(),
token_expiry: 3600,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ObservabilityConfig {
pub metrics: bool,
pub tracing: bool,
pub prometheus_endpoint: String,
}
impl Default for ObservabilityConfig {
fn default() -> Self {
Self {
metrics: true,
tracing: true,
prometheus_endpoint: "/metrics".to_string(),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct LimitsConfig {
pub max_requests_per_sec: u64,
pub burst_size: u64,
}
impl Default for LimitsConfig {
fn default() -> Self {
Self {
max_requests_per_sec: 100,
burst_size: 50,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ElectionConfig {
pub enabled: bool,
pub strategy: String,
pub lease_duration: u64,
}
impl Default for ElectionConfig {
fn default() -> Self {
Self {
enabled: false,
strategy: "memory".to_string(),
lease_duration: 30,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct VaultConfig {
pub url: String,
pub token: String,
pub kv_path: String,
pub lease_duration: u64,
}
impl Default for VaultConfig {
fn default() -> Self {
Self {
url: "http://localhost:8200".to_string(),
token: "root".to_string(),
kv_path: "secret/sunbeam".to_string(),
lease_duration: 30,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_service_config_default() {
let config = ServiceConfig::default();
assert_eq!(config.name, "sunbeam-g2v");
assert_eq!(config.environment, "development");
assert_eq!(config.host, "0.0.0.0");
assert_eq!(config.port, 8080);
assert!(!config.debug);
assert_eq!(config.log_level, "info");
}
#[test]
fn test_database_config_default() {
let config = DatabaseConfig::default();
assert_eq!(config.url, "postgres://localhost:5432/sunbeam");
assert_eq!(config.max_connections, 10);
assert_eq!(config.connect_timeout, 30);
}
#[test]
fn test_nats_config_default() {
let config = NatsConfig::default();
assert_eq!(config.url, "nats://localhost:4222");
assert!(config.jetstream);
}
#[test]
fn test_auth_config_default() {
let config = AuthConfig::default();
assert_eq!(config.jwt_secret, "change-me");
assert_eq!(config.token_expiry, 3600);
}
#[test]
fn test_observability_config_default() {
let config = ObservabilityConfig::default();
assert!(config.metrics);
assert!(config.tracing);
assert_eq!(config.prometheus_endpoint, "/metrics");
}
#[test]
fn test_limits_config_default() {
let config = LimitsConfig::default();
assert_eq!(config.max_requests_per_sec, 100);
assert_eq!(config.burst_size, 50);
}
#[test]
fn test_election_config_default() {
let config = ElectionConfig::default();
assert!(!config.enabled);
assert_eq!(config.strategy, "memory");
assert_eq!(config.lease_duration, 30);
}
#[test]
fn test_vault_config_default() {
let config = VaultConfig::default();
assert_eq!(config.url, "http://localhost:8200");
assert_eq!(config.token, "root");
assert_eq!(config.kv_path, "secret/sunbeam");
}
}