refactor configs into a crate
This commit is contained in:
53
apps/api/src/configs/database.rs
Normal file
53
apps/api/src/configs/database.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use config::{Config, ConfigError};
|
||||
use tracing::warn;
|
||||
|
||||
use super::{
|
||||
FromConfig,
|
||||
key::{DATABASE_MAX_CONNECTIONS_KEY, DATABASE_MIGRATE_ON_STARTUP_KEY},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DatabaseSettings {
|
||||
pub url: String,
|
||||
pub max_connections: u32,
|
||||
pub migrate_on_startup: bool,
|
||||
}
|
||||
|
||||
impl FromConfig for DatabaseSettings {
|
||||
fn from_config(_config: &Config) -> Result<Self, String> {
|
||||
Ok(DatabaseSettings {
|
||||
url: _config
|
||||
.get_string(super::key::DATABASE_URL_KEY)
|
||||
.map_err(|op| match op {
|
||||
ConfigError::NotFound(_) => "Database URL not found in configuration".into(),
|
||||
err => {
|
||||
format!("Failed to read Database URL from configuration {err}")
|
||||
}
|
||||
})?,
|
||||
max_connections: _config
|
||||
.get_int(DATABASE_MAX_CONNECTIONS_KEY)
|
||||
.unwrap_or_else(|err| {
|
||||
const DEFAULT_MAX_CONNECTIONS: i64 = 10;
|
||||
warn!(
|
||||
"{} not set or invalid in configuration, defaulting to {}. Error: {}",
|
||||
DATABASE_MAX_CONNECTIONS_KEY, DEFAULT_MAX_CONNECTIONS, err
|
||||
);
|
||||
DEFAULT_MAX_CONNECTIONS
|
||||
}) as u32,
|
||||
migrate_on_startup: _config
|
||||
.get_bool(DATABASE_MIGRATE_ON_STARTUP_KEY)
|
||||
.unwrap_or_else(|err| {
|
||||
const DEFAULT_MIGRATE_ON_STARTUP: bool = true;
|
||||
warn!(
|
||||
"{} not set or invalid in configuration, defaulting to {}. Error: {}",
|
||||
DATABASE_MIGRATE_ON_STARTUP_KEY, DEFAULT_MIGRATE_ON_STARTUP, err
|
||||
);
|
||||
DEFAULT_MIGRATE_ON_STARTUP
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
9
apps/api/src/configs/key.rs
Normal file
9
apps/api/src/configs/key.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
pub(crate) const LOGGING_LEVEL_KEY: &str = "LOGGING.LEVEL";
|
||||
pub(crate) const LOGGING_UTC_KEY: &str = "LOGGING.UTC";
|
||||
//
|
||||
pub(crate) const SERVER_ADDRESS_KEY: &str = "SERVER.ADDRESS";
|
||||
pub(crate) const SERVER_PORT_KEY: &str = "SERVER.PORT";
|
||||
//
|
||||
pub(crate) const DATABASE_URL_KEY: &str = "DATABASE.URL";
|
||||
pub(crate) const DATABASE_MAX_CONNECTIONS_KEY: &str = "DATABASE.MAX_CONNECTIONS";
|
||||
pub(crate) const DATABASE_MIGRATE_ON_STARTUP_KEY: &str = "DATABASE.MIGRATION.MIGRATE_ON_STARTUP";
|
||||
52
apps/api/src/configs/logging.rs
Normal file
52
apps/api/src/configs/logging.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use config::{Config, ConfigError};
|
||||
use tracing::{Level, warn};
|
||||
|
||||
use super::{
|
||||
FromConfig,
|
||||
key::{LOGGING_LEVEL_KEY, LOGGING_UTC_KEY},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LoggingSettings {
|
||||
pub level: Level,
|
||||
pub utc: bool,
|
||||
}
|
||||
|
||||
impl FromConfig for LoggingSettings {
|
||||
fn from_config(_config: &Config) -> Result<Self, String> {
|
||||
const DEFAULT_LOGGING_LEVEL: Level = Level::INFO;
|
||||
Ok(LoggingSettings {
|
||||
level: _config
|
||||
.get_string(LOGGING_LEVEL_KEY)
|
||||
.unwrap_or_else(|err| {
|
||||
warn!(
|
||||
"Failed to read {} from configuration, defaulting to {}. Error: {}",
|
||||
LOGGING_LEVEL_KEY, DEFAULT_LOGGING_LEVEL, err
|
||||
);
|
||||
DEFAULT_LOGGING_LEVEL.to_string()
|
||||
})
|
||||
.parse()
|
||||
.unwrap_or_else(|err| {
|
||||
warn!(
|
||||
"Invalid logging level in configuration, defaulting to {}. Error: {}",
|
||||
DEFAULT_LOGGING_LEVEL, err
|
||||
);
|
||||
DEFAULT_LOGGING_LEVEL
|
||||
}),
|
||||
utc: _config
|
||||
.get_bool(LOGGING_UTC_KEY)
|
||||
.unwrap_or_else(|err: ConfigError| {
|
||||
const DEFAULT_UTC: bool = false;
|
||||
warn!(
|
||||
"Invalid UTC setting in configuration, defaulting to {}. Error: {}",
|
||||
DEFAULT_UTC, err
|
||||
);
|
||||
DEFAULT_UTC
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
56
apps/api/src/configs/server.rs
Normal file
56
apps/api/src/configs/server.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use std::net::IpAddr;
|
||||
|
||||
use config::{Config, ConfigError};
|
||||
use tracing::warn;
|
||||
|
||||
use super::{
|
||||
FromConfig,
|
||||
key::{SERVER_ADDRESS_KEY, SERVER_PORT_KEY},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServerSettings {
|
||||
pub address: IpAddr,
|
||||
pub port: u16,
|
||||
}
|
||||
|
||||
impl FromConfig for ServerSettings {
|
||||
fn from_config(_config: &Config) -> Result<Self, String> {
|
||||
Ok(ServerSettings {
|
||||
address: _config
|
||||
.get_string(SERVER_ADDRESS_KEY)
|
||||
.unwrap_or_else(|err| {
|
||||
const DEFAULT_ADDRESS: &str = "0.0.0.0";
|
||||
match err {
|
||||
ConfigError::NotFound(_) => {}
|
||||
_ => {
|
||||
warn!(
|
||||
"Failed to read {} from configuration, defaulting to {}. Error: {}",
|
||||
SERVER_ADDRESS_KEY, DEFAULT_ADDRESS, err
|
||||
);
|
||||
}
|
||||
};
|
||||
DEFAULT_ADDRESS.to_string()
|
||||
})
|
||||
.parse()
|
||||
.map_err(|e| format!("Invalid {} in configuration: {}", SERVER_ADDRESS_KEY, e))?,
|
||||
|
||||
port: _config.get_int(SERVER_PORT_KEY).unwrap_or_else(|err| {
|
||||
const DEFAULT_PORT: i64 = 8080;
|
||||
warn!(
|
||||
"{} not set or invalid in configuration, defaulting to {}. Error: {}",
|
||||
SERVER_PORT_KEY, DEFAULT_PORT, err
|
||||
);
|
||||
DEFAULT_PORT
|
||||
}) as u16,
|
||||
})
|
||||
}
|
||||
|
||||
fn validate(&self) -> Result<(), String> {
|
||||
#[allow(clippy::absurd_extreme_comparisons, unused_comparisons)]
|
||||
if self.port == 0 || self.port > 65535 {
|
||||
return Err("Server port must be between 1 and 65535".into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user