use serde::{Deserialize, Serialize};
use crate::config::ConfigError;
use crate::config::{AuthConfig, ServerConfig, TimeoutConfig};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct AppConfig {
pub server: ServerConfig,
#[serde(alias = "auth")]
pub authentication: AuthConfig,
pub timeout: Option<TimeoutConfig>,
}
impl AppConfig {
pub fn builder() -> AppConfigBuilder {
AppConfigBuilder::default()
}
pub fn validate(&self) -> Result<(), ConfigError> {
self.server.validate()?;
self.authentication.validate()?;
if let Some(ref timeout) = self.timeout {
timeout.validate()?;
}
Ok(())
}
}
impl crate::config::ValidateConfig for AppConfig {
fn validate(&self) -> Result<(), crate::config::ConfigError> {
AppConfig::validate(self)
}
}
impl Default for AppConfig {
fn default() -> Self {
Self {
server: ServerConfig::default(),
authentication: AuthConfig::default(),
timeout: Some(TimeoutConfig::default()),
}
}
}
#[derive(Default)]
pub struct AppConfigBuilder {
server: Option<ServerConfig>,
authentication: Option<AuthConfig>,
timeout: Option<TimeoutConfig>,
}
impl AppConfigBuilder {
pub fn server(mut self, server: ServerConfig) -> Self {
self.server = Some(server);
self
}
pub fn authentication(mut self, authentication: AuthConfig) -> Self {
self.authentication = Some(authentication);
self
}
pub fn timeout(mut self, timeout: TimeoutConfig) -> Self {
self.timeout = Some(timeout);
self
}
pub fn build(self) -> Result<AppConfig, crate::config::ConfigError> {
let config = AppConfig {
server: self.server.unwrap_or_default(),
authentication: self.authentication.unwrap_or_default(),
timeout: self.timeout.or_else(|| Some(TimeoutConfig::default())),
};
config.validate()?;
Ok(config)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_app_config_default() {
let config = AppConfig::default();
assert_eq!(config.server.host, "127.0.0.1"); assert_eq!(config.server.port, 8080);
assert!(config.timeout.is_some());
assert_eq!(config.timeout.as_ref().unwrap().default_timeout_secs, 30);
}
#[test]
fn test_app_config_builder() {
let result = AppConfig::builder()
.server(ServerConfig {
host: "127.0.0.1".to_string(),
port: 9000,
request_timeout_secs: 30, cors: None,
})
.build();
let config = result.expect("Failed to build config");
assert_eq!(config.server.host, "127.0.0.1");
assert_eq!(config.server.port, 9000);
}
}