use super::api_config::ApiConfig;
#[cfg(feature = "postgres-backend")]
use myc_adapters_shared_lib::models::RedisConfig;
#[cfg(feature = "standalone")]
use myc_config::optional_config::OptionalConfig;
#[cfg(feature = "postgres-backend")]
use myc_config::{optional_config::OptionalConfig, VaultConfig};
use myc_core::models::CoreConfig;
#[cfg(feature = "postgres-backend")]
use myc_diesel::models::config::DieselConfig;
#[cfg(feature = "standalone")]
use myc_diesel_sqlite::config::SqliteConfig;
use myc_http_tools::models::auth_config::AuthConfig;
#[cfg(feature = "standalone")]
use myc_notifier::models::LocalEmailConfig;
use myc_notifier::models::{QueueConfig, SmtpConfig};
use mycelium_base::utils::errors::MappedErrors;
use std::path::PathBuf;
#[derive(Clone)]
pub struct ConfigHandler {
pub core: CoreConfig,
pub api: ApiConfig,
pub auth: AuthConfig,
pub queue: QueueConfig,
#[cfg(feature = "postgres-backend")]
pub diesel: DieselConfig,
#[cfg(feature = "postgres-backend")]
pub smtp: SmtpConfig,
#[cfg(feature = "postgres-backend")]
pub redis: RedisConfig,
#[cfg(feature = "postgres-backend")]
pub vault: OptionalConfig<VaultConfig>,
#[cfg(feature = "standalone")]
pub sqlite: SqliteConfig,
#[cfg(feature = "standalone")]
pub smtp: OptionalConfig<SmtpConfig>,
#[cfg(feature = "standalone")]
pub local_email: OptionalConfig<LocalEmailConfig>,
}
impl ConfigHandler {
pub fn init_from_file(file: PathBuf) -> Result<Self, MappedErrors> {
Ok(Self {
core: CoreConfig::from_default_config_file(file.clone())?,
api: ApiConfig::from_default_config_file(file.clone())?,
auth: AuthConfig::from_default_config_file(file.clone())?,
queue: QueueConfig::from_default_config_file(file.clone())?,
#[cfg(feature = "postgres-backend")]
diesel: DieselConfig::from_default_config_file(file.clone())?,
#[cfg(feature = "postgres-backend")]
smtp: SmtpConfig::from_default_config_file(file.clone())?,
#[cfg(feature = "postgres-backend")]
redis: RedisConfig::from_default_config_file(file.clone())?,
#[cfg(feature = "postgres-backend")]
vault: VaultConfig::from_default_config_file(file.clone())?,
#[cfg(feature = "standalone")]
sqlite: SqliteConfig::from_default_config_file(file.clone())?,
#[cfg(feature = "standalone")]
smtp: SmtpConfig::from_optional_config_file(file.clone())?,
#[cfg(feature = "standalone")]
local_email: LocalEmailConfig::from_optional_config_file(
file.clone(),
)?,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "postgres-backend")]
#[test]
fn config_full_example_toml_parses_into_config_handler() {
let file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../settings/config.full.example.toml");
ConfigHandler::init_from_file(file).unwrap();
}
#[cfg(feature = "standalone")]
#[test]
fn config_standalone_example_toml_parses_into_config_handler() {
let file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../settings/config.standalone.example.toml");
let config = ConfigHandler::init_from_file(file).unwrap();
assert!(matches!(config.local_email, OptionalConfig::Disabled));
}
#[cfg(feature = "standalone")]
#[test]
fn local_email_dir_wires_through_to_file_transport() {
use myc_notifier::repositories::{
select_local_transport, LocalTransportKind,
};
use std::io::Write;
let base = std::fs::read_to_string(
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../../settings/config.standalone.example.toml"),
)
.unwrap();
let dir = std::env::temp_dir()
.join(format!("myc_local_email_{}", std::process::id()));
let with_local_email = format!(
"{base}\n[localEmail.define]\ndir = \"{}\"\n",
dir.to_str().unwrap()
);
let config_path = std::env::temp_dir().join(format!(
"myc_config_local_email_{}.toml",
std::process::id()
));
let mut handle = std::fs::File::create(&config_path).unwrap();
handle.write_all(with_local_email.as_bytes()).unwrap();
let config =
ConfigHandler::init_from_file(config_path.clone()).unwrap();
let OptionalConfig::Enabled(local_email) = config.local_email else {
panic!("[localEmail] should resolve to Enabled");
};
assert_eq!(local_email.dir, dir);
let _ = std::fs::remove_dir_all(&dir);
assert!(!dir.exists());
let resolved = local_email.ensure_dir().unwrap();
assert!(dir.is_dir());
let selected = select_local_transport(None, Some(resolved));
assert!(matches!(selected, LocalTransportKind::File(_)));
let _ = std::fs::remove_file(&config_path);
let _ = std::fs::remove_dir_all(&dir);
}
}