use clappconfig::{AppConfig, anyhow, clap::ArgMatches}; use std::collections::HashMap; use std::time::Duration; #[derive(Debug, Serialize, Deserialize)] #[serde(default)] #[serde(deny_unknown_fields)] pub(crate) struct Config { /// Log level pub(crate) logging: String, /// Per-module log levels pub(crate) log_levels: HashMap, /// Server bind address pub(crate) host: String, /// Server port pub(crate) port: u16, /// Default expiry time in seconds #[serde(with = "serde_duration_secs")] pub(crate) default_expiry: Duration, /// Max expiry time in seconds #[serde(with = "serde_duration_secs")] pub(crate) max_expiry: Duration, /// Expired post clearing interval (triggered on write) #[serde(with = "serde_duration_secs")] pub(crate) expired_gc_interval: Duration, /// Max uploaded file size in bytes pub(crate) max_file_size: usize, } impl Default for Config { fn default() -> Self { Self { logging: "debug".to_string(), log_levels: Default::default(), host: "0.0.0.0".to_string(), port: 7745, default_expiry: Duration::from_secs(60 * 10), max_expiry: Duration::from_secs(60 * 10), expired_gc_interval: Duration::from_secs(60), max_file_size: 1 * (1024 * 1024) // 1MB } } } impl AppConfig for Config { type Init = Config; fn logging(&self) -> &str { &self.logging } fn logging_mod_levels(&self) -> Option<&HashMap> { Some(&self.log_levels) } fn configure(self, _clap: &ArgMatches) -> anyhow::Result { Ok(self) } } mod serde_duration_secs { use serde::{self, Deserialize, Serializer, Deserializer}; use std::time::Duration; pub fn serialize( value: &Duration, se: S, ) -> Result where S: Serializer, { se.serialize_u64(value.as_secs()) } pub fn deserialize<'de, D>( de: D, ) -> Result where D: Deserializer<'de>, { let s: u64 = u64::deserialize(de)?; Ok(Duration::from_secs(s)) } }