use serde::Deserialize;
#[derive(Debug, Default, Deserialize, Clone)]
pub struct ServerSection {
#[serde(default = "default_host")]
pub host: String,
#[serde(default = "default_port")]
pub port: u16,
}
#[derive(Debug, Default, Deserialize, Clone)]
pub struct LimitsSection {
#[serde(default = "default_max_clients")]
pub max_clients: usize,
#[serde(default = "default_max_rooms")]
pub max_rooms: usize,
#[serde(default = "default_max_message_size")]
pub max_message_size: usize,
#[serde(default = "default_max_username_len")]
pub max_username_len: usize,
}
#[derive(Debug, Default, Deserialize, Clone)]
pub struct HeartbeatSection {
#[serde(default = "default_ping_interval")]
pub ping_interval_secs: u64,
#[serde(default = "default_pong_timeout")]
pub pong_timeout_secs: u64,
}
#[derive(Debug, Default, Deserialize, Clone)]
pub struct BroadcastSection {
#[serde(default)]
pub api_key: String,
}
#[derive(Debug, Deserialize, Clone)]
pub struct AppConfig {
#[serde(default)]
pub server: ServerSection,
#[serde(default)]
pub limits: LimitsSection,
#[serde(default)]
pub heartbeat: HeartbeatSection,
#[serde(default)]
pub broadcast: BroadcastSection,
}
fn default_host() -> String {
"0.0.0.0".into()
}
fn default_port() -> u16 {
3000
}
fn default_max_clients() -> usize {
1000
}
fn default_max_rooms() -> usize {
100
}
fn default_max_message_size() -> usize {
8192
}
fn default_max_username_len() -> usize {
32
}
fn default_ping_interval() -> u64 {
30
}
fn default_pong_timeout() -> u64 {
10
}
pub fn load_config() -> Result<AppConfig, config::ConfigError> {
let c = config::Config::builder()
.add_source(config::File::with_name("openws").required(false))
.add_source(
config::Environment::with_prefix("OPENWS")
.separator("_")
.try_parsing(true),
)
.build()?;
let mut cfg: AppConfig = c.try_deserialize()?;
if let Ok(v) = std::env::var("OPENWS_PORT") {
if let Ok(p) = v.parse() {
cfg.server.port = p;
}
}
if let Ok(v) = std::env::var("OPENWS_MAX_CLIENTS") {
if let Ok(n) = v.parse() {
cfg.limits.max_clients = n;
}
}
if let Ok(v) = std::env::var("OPENWS_PING_INTERVAL") {
if let Ok(s) = v.parse() {
cfg.heartbeat.ping_interval_secs = s;
}
}
if let Ok(v) = std::env::var("OPENWS_API_KEY") {
cfg.broadcast.api_key = v;
}
Ok(cfg)
}
pub fn mask_api_key(key: &str) -> String {
if key.is_empty() {
return "(none)".into();
}
if key.len() <= 4 {
return "****".into();
}
format!("{}****", &key[..4])
}