use schemars::JsonSchema;
use serde::Deserialize;
use spring::config::Configurable;
use std::net::{IpAddr, Ipv4Addr};
use tracing::Level;
#[derive(Debug, Configurable, JsonSchema, Deserialize)]
#[config_prefix = "web"]
pub struct WebConfig {
#[serde(flatten)]
pub(crate) server: ServerConfig,
pub(crate) middlewares: Option<Middlewares>,
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct ServerConfig {
#[serde(default = "default_binding")]
pub(crate) binding: IpAddr,
#[serde(default = "default_port")]
pub(crate) port: u16,
#[serde(default)]
pub(crate) connect_info: bool,
#[serde(default)]
pub(crate) graceful: bool,
}
fn default_binding() -> IpAddr {
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))
}
fn default_port() -> u16 {
8080
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct Middlewares {
pub compression: Option<EnableMiddleware>,
pub limit_payload: Option<LimitPayloadMiddleware>,
pub logger: Option<TraceLoggerMiddleware>,
pub catch_panic: Option<EnableMiddleware>,
pub timeout_request: Option<TimeoutRequestMiddleware>,
pub cors: Option<CorsMiddleware>,
#[serde(rename = "static")]
pub static_assets: Option<StaticAssetsMiddleware>,
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct StaticAssetsMiddleware {
pub enable: bool,
#[serde(default = "bool::default")]
pub must_exist: bool,
#[serde(default = "default_fallback")]
pub fallback: String,
#[serde(default = "bool::default")]
pub precompressed: bool,
#[serde(default = "default_assets_uri")]
pub uri: String,
#[serde(default = "default_assets_path")]
pub path: String,
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct TraceLoggerMiddleware {
pub enable: bool,
pub level: LogLevel,
}
#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]
pub enum LogLevel {
#[serde(rename = "trace")]
Trace,
#[serde(rename = "debug")]
Debug,
#[serde(rename = "info")]
#[default]
Info,
#[serde(rename = "warn")]
Warn,
#[serde(rename = "error")]
Error,
}
#[allow(clippy::from_over_into)]
impl Into<Level> for LogLevel {
fn into(self) -> Level {
match self {
Self::Trace => Level::TRACE,
Self::Debug => Level::DEBUG,
Self::Info => Level::INFO,
Self::Warn => Level::WARN,
Self::Error => Level::ERROR,
}
}
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct CorsMiddleware {
pub enable: bool,
pub allow_origins: Option<Vec<String>>,
pub allow_headers: Option<Vec<String>>,
pub allow_methods: Option<Vec<String>>,
pub max_age: Option<u64>,
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct TimeoutRequestMiddleware {
pub enable: bool,
pub timeout: u64,
}
#[derive(Debug, Clone, JsonSchema, Deserialize)]
pub struct LimitPayloadMiddleware {
pub enable: bool,
pub body_limit: String,
}
#[derive(Debug, PartialEq, Clone, JsonSchema, Deserialize)]
pub struct EnableMiddleware {
pub enable: bool,
}
fn default_assets_path() -> String {
"static".to_string()
}
fn default_assets_uri() -> String {
"/static".to_string()
}
fn default_fallback() -> String {
"index.html".to_string()
}