use config::{Config, ConfigError, File};
use serde::Deserialize;
use std::path::Path;
#[derive(Debug, Deserialize, Clone)]
pub struct ServerConfig {
#[serde(default = "default_host")]
pub host: String,
#[serde(default = "default_port")]
pub port: u16,
}
impl Default for ServerConfig {
fn default() -> Self {
Self {
host: default_host(),
port: default_port(),
}
}
}
fn default_host() -> String {
"0.0.0.0".to_string()
}
fn default_port() -> u16 {
3000
}
#[derive(Debug, Deserialize, Clone)]
pub struct RedisConfig {
#[serde(default = "default_redis_url")]
pub url: String,
}
fn default_redis_url() -> String {
"redis://127.0.0.1:6379".to_string()
}
impl Default for RedisConfig {
fn default() -> Self {
Self {
url: default_redis_url(),
}
}
}
#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
#[serde(default)]
pub server: ServerConfig,
#[serde(default)]
pub redis: RedisConfig,
}
impl Default for AppConfig {
fn default() -> Self {
Self {
server: ServerConfig {
host: default_host(),
port: default_port(),
},
redis: RedisConfig {
url: default_redis_url(),
},
}
}
}
impl AppConfig {
pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self, ConfigError> {
let path = path.as_ref();
if !path.exists() {
return Ok(Self::default());
}
let s = Config::builder().add_source(File::from(path)).build()?;
s.try_deserialize()
}
}