use serde::Deserialize; use config::Config; #[derive(Deserialize, Debug)] pub struct AppConfig { pub server_port: u16, pub nats_addr: String, pub data_persistence_service_url: String, pub report_generator_service_url: String, pub provider_services: Vec, } impl AppConfig { pub fn load() -> Result { let cfg: Config = config::Config::builder() .add_source(config::Environment::default().separator("__")) .build()?; let server_port: u16 = cfg.get::("server_port")?; let nats_addr: String = cfg.get::("nats_addr")?; let data_persistence_service_url: String = cfg.get::("data_persistence_service_url")?; let report_generator_service_url: String = cfg.get::("report_generator_service_url") .unwrap_or_else(|_| "http://report-generator-service:8004".to_string()); // Parse provider_services deterministically: // 1) prefer array from env (e.g., PROVIDER_SERVICES__0, PROVIDER_SERVICES__1, ...) // 2) fallback to explicit JSON in PROVIDER_SERVICES let provider_services: Vec = if let Ok(arr) = cfg.get_array("provider_services") { let mut out: Vec = Vec::with_capacity(arr.len()); for v in arr { let s = v.into_string().map_err(|e| { config::ConfigError::Message(format!("provider_services must be strings: {}", e)) })?; out.push(s); } out } else { let json = cfg.get_string("provider_services")?; serde_json::from_str::>(&json).map_err(|e| { config::ConfigError::Message(format!( "Invalid JSON for provider_services: {}", e )) })? }; Ok(Self { server_port, nats_addr, data_persistence_service_url, report_generator_service_url, provider_services, }) } }