use crate::Result;
use serde::{Deserialize, Serialize};
use std::path::Path;
mod env;
mod loader;
mod validation;
#[cfg(test)]
mod tests;
const DEFAULT_HOST: &str = "127.0.0.1";
const DEFAULT_PORT: u16 = 8000;
const DEFAULT_MAX_REQUEST_BODY_BYTES: usize = 104_857_600;
const DEFAULT_MAX_MULTIPART_FIELD_BYTES: usize = 104_857_600;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default)]
pub struct ServerConfig {
#[serde(default = "default_host")]
pub host: String,
#[serde(default = "default_port")]
pub port: u16,
#[serde(default)]
pub cors_origins: Vec<String>,
#[serde(default = "default_max_request_body_bytes")]
pub max_request_body_bytes: usize,
#[serde(default = "default_max_multipart_field_bytes")]
pub max_multipart_field_bytes: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_upload_mb: Option<usize>,
}
impl Default for ServerConfig {
fn default() -> Self {
Self {
host: default_host(),
port: default_port(),
cors_origins: Vec::new(),
max_request_body_bytes: default_max_request_body_bytes(),
max_multipart_field_bytes: default_max_multipart_field_bytes(),
max_upload_mb: None,
}
}
}
fn default_host() -> String {
DEFAULT_HOST.to_string()
}
fn default_port() -> u16 {
DEFAULT_PORT
}
fn default_max_request_body_bytes() -> usize {
DEFAULT_MAX_REQUEST_BODY_BYTES
}
fn default_max_multipart_field_bytes() -> usize {
DEFAULT_MAX_MULTIPART_FIELD_BYTES
}
impl ServerConfig {
pub fn new() -> Self {
Self::default()
}
pub fn listen_addr(&self) -> String {
format!("{}:{}", self.host, self.port)
}
pub fn cors_allows_all(&self) -> bool {
self.cors_origins.is_empty()
}
pub fn is_origin_allowed(&self, origin: &str) -> bool {
self.cors_origins.is_empty() || self.cors_origins.contains(&origin.to_string())
}
pub fn max_request_body_mb(&self) -> usize {
self.max_request_body_bytes.div_ceil(1_048_576)
}
pub fn max_multipart_field_mb(&self) -> usize {
self.max_multipart_field_bytes.div_ceil(1_048_576)
}
pub fn normalize_legacy_fields(&mut self) {
validation::normalize_legacy_fields(self.max_upload_mb, &mut self.max_multipart_field_bytes);
}
pub fn apply_env_overrides(&mut self) -> Result<()> {
env::apply_env_overrides(
&mut self.host,
&mut self.port,
&mut self.cors_origins,
&mut self.max_request_body_bytes,
&mut self.max_multipart_field_bytes,
&mut self.max_upload_mb,
)?;
self.normalize_legacy_fields();
Ok(())
}
pub fn from_file(path: impl AsRef<Path>) -> Result<Self> {
loader::from_file(path)
}
pub fn from_toml_file(path: impl AsRef<Path>) -> Result<Self> {
loader::from_toml_file(path)
}
pub fn from_yaml_file(path: impl AsRef<Path>) -> Result<Self> {
loader::from_yaml_file(path)
}
pub fn from_json_file(path: impl AsRef<Path>) -> Result<Self> {
loader::from_json_file(path)
}
}