use crate::config::env::{env, Environment};
#[derive(Debug, Clone)]
pub struct AppConfig {
pub name: String,
pub environment: Environment,
pub debug: bool,
pub url: String,
pub inline_budget_threshold_bytes: usize,
}
impl AppConfig {
pub fn from_env() -> Self {
Self {
name: env("APP_NAME", "Ferro Application".to_string()),
environment: Environment::detect(),
debug: env("APP_DEBUG", true),
url: env("APP_URL", "http://localhost:8080".to_string()),
inline_budget_threshold_bytes: env(
"INLINE_BUDGET_BYTES",
crate::telemetry::inline_budget::DEFAULT_INLINE_BUDGET_THRESHOLD_BYTES,
),
}
}
pub fn builder() -> AppConfigBuilder {
AppConfigBuilder::default()
}
pub fn is_debug(&self) -> bool {
self.debug
}
pub fn is_production(&self) -> bool {
self.environment.is_production()
}
pub fn is_development(&self) -> bool {
self.environment.is_development()
}
}
impl Default for AppConfig {
fn default() -> Self {
Self::from_env()
}
}
#[derive(Default)]
pub struct AppConfigBuilder {
name: Option<String>,
environment: Option<Environment>,
debug: Option<bool>,
url: Option<String>,
inline_budget_threshold_bytes: Option<usize>,
}
impl AppConfigBuilder {
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn environment(mut self, env: Environment) -> Self {
self.environment = Some(env);
self
}
pub fn debug(mut self, debug: bool) -> Self {
self.debug = Some(debug);
self
}
pub fn url(mut self, url: impl Into<String>) -> Self {
self.url = Some(url.into());
self
}
pub fn inline_budget_threshold_bytes(mut self, bytes: usize) -> Self {
self.inline_budget_threshold_bytes = Some(bytes);
self
}
pub fn build(self) -> AppConfig {
let default = AppConfig::from_env();
AppConfig {
name: self.name.unwrap_or(default.name),
environment: self.environment.unwrap_or(default.environment),
debug: self.debug.unwrap_or(default.debug),
url: self.url.unwrap_or(default.url),
inline_budget_threshold_bytes: self
.inline_budget_threshold_bytes
.unwrap_or(default.inline_budget_threshold_bytes),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use serial_test::serial;
#[test]
#[serial]
fn inline_budget_threshold_default() {
std::env::remove_var("INLINE_BUDGET_BYTES");
let cfg = AppConfig::from_env();
assert_eq!(cfg.inline_budget_threshold_bytes, 102_400);
}
#[test]
#[serial]
fn inline_budget_threshold_env_override() {
std::env::set_var("INLINE_BUDGET_BYTES", "50000");
let cfg = AppConfig::from_env();
assert_eq!(cfg.inline_budget_threshold_bytes, 50_000);
std::env::remove_var("INLINE_BUDGET_BYTES");
}
#[test]
#[serial]
fn inline_budget_threshold_builder_override() {
let cfg = AppConfigBuilder::default()
.inline_budget_threshold_bytes(200_000)
.build();
assert_eq!(cfg.inline_budget_threshold_bytes, 200_000);
}
}