aboutsummaryrefslogtreecommitdiffstats
path: root/lib/warden-core/src/config/mod.rs
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2026-03-29 16:15:54 +0200
committerrtkay123 <dev@kanjala.com>2026-03-29 16:15:54 +0200
commit57c4a5251c30d3dc2b78059fd208d8948d999056 (patch)
tree43d86334ad8c08305b9cadda3a524016e0ea4cfc /lib/warden-core/src/config/mod.rs
parentc02a5a74d637bab34dc85a0f8a6cfd2a69fd6597 (diff)
downloadwarden-57c4a5251c30d3dc2b78059fd208d8948d999056.tar.bz2
warden-57c4a5251c30d3dc2b78059fd208d8948d999056.zip
refactor: move config to core
Diffstat (limited to 'lib/warden-core/src/config/mod.rs')
-rw-r--r--lib/warden-core/src/config/mod.rs120
1 files changed, 120 insertions, 0 deletions
diff --git a/lib/warden-core/src/config/mod.rs b/lib/warden-core/src/config/mod.rs
new file mode 100644
index 0000000..9d0c937
--- /dev/null
+++ b/lib/warden-core/src/config/mod.rs
@@ -0,0 +1,120 @@
+pub mod cli;
+mod log_level;
+
+use std::path::PathBuf;
+
+use clap::ValueEnum;
+pub use cli::Cli;
+pub use cli::Commands;
+use serde::Deserialize;
+use tracing_subscriber::EnvFilter;
+
+use crate::WardenError;
+use crate::config::cli::CliEnvironment;
+use crate::config::cli::database::Database;
+
+#[derive(Deserialize, Default, Debug, ValueEnum, Clone, Copy)]
+#[serde(rename_all = "lowercase")]
+pub enum Environment {
+ Development,
+ #[default]
+ Production,
+}
+
+impl From<CliEnvironment> for Environment {
+ fn from(value: CliEnvironment) -> Self {
+ match value {
+ CliEnvironment::Dev | CliEnvironment::Development => Self::Development,
+ CliEnvironment::Prod | CliEnvironment::Production => Self::Production,
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub struct Configuration {
+ pub server: Server,
+ pub database: Database,
+}
+
+#[derive(Debug, Clone)]
+pub struct Server {
+ pub port: u16,
+ pub environment: Environment,
+ pub log_level: EnvFilter,
+ pub log_dir: PathBuf,
+ pub timeout_secs: u64,
+}
+
+impl Server {
+ fn merge(cli: &Cli, file: &Cli, missing: &mut Vec<&str>) -> Result<Self, WardenError> {
+ let port = cli.server.port.or(file.server.port);
+
+ if port.is_none() {
+ missing.push("server.port");
+ }
+
+ let timeout = cli.server.timeout_secs.or(file.server.timeout_secs);
+
+ if timeout.is_none() {
+ missing.push("server.timeout");
+ }
+
+ let log_dir = cli.server.log_dir.clone().or(file.server.log_dir.clone());
+
+ if log_dir.is_none() {
+ missing.push("server.log_dir");
+ }
+
+ let log_level = cli
+ .server
+ .log_level
+ .as_ref()
+ .or(file.server.log_level.as_ref())
+ .map(ToOwned::to_owned);
+
+ if log_level.is_none() {
+ missing.push("server.log_level");
+ }
+
+ let environment = cli.server.environment.or(file.server.environment);
+
+ if environment.is_none() {
+ missing.push("server.environment");
+ }
+
+ if !missing.is_empty() {
+ let err = missing
+ .iter()
+ .map(|f| format!(" - {}", f))
+ .collect::<Vec<_>>()
+ .join("\n");
+ return Err(WardenError::Config(err));
+ }
+
+ let log_level =
+ tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| {
+ // axum logs rejections from built-in extractors with the `axum::rejection`
+ // target, at `TRACE` level. `axum::rejection=trace` enables showing those events
+ log_level.unwrap().into()
+ });
+
+ Ok(Self {
+ port: port.unwrap(),
+ environment: environment.unwrap().into(),
+ log_dir: log_dir.unwrap(),
+ timeout_secs: timeout.unwrap(),
+ log_level,
+ })
+ }
+}
+
+impl Configuration {
+ pub fn merge(cli: &Cli, file: &Cli) -> Result<Self, WardenError> {
+ let mut missing = Vec::new();
+
+ let server = Server::merge(cli, file, &mut missing)?;
+ let database = Database::merge(&cli.database, &file.database)?;
+
+ Ok(Self { server, database })
+ }
+}