use crate::Scanner;
use config::builder::{AsyncState, DefaultState};
use config::{ConfigBuilder, Environment};
pub struct Assembler;
pub struct AssemblerChoices {
pub dir_name: Option<String>,
pub env_enabled: bool,
pub env_prefix: Option<String>,
pub env_separator: Option<String>,
}
impl Default for AssemblerChoices {
fn default() -> Self {
Self {
dir_name: Some("config".to_string()),
env_enabled: true,
env_prefix: Some("APP".to_string()),
env_separator: Some("_".to_string()),
}
}
}
macro_rules! bootstrap_builder {
($builder:expr, $choices:expr) => {{
let mut builder = $builder;
for config_file in Scanner::find_config_files($choices.dir_name.as_deref()) {
builder = builder.add_source(config::File::from(config_file));
}
if $choices.env_enabled {
let mut env_source = Environment::default();
if let Some(prefix) = $choices.env_prefix.as_deref() {
env_source = env_source.prefix(prefix);
}
if let Some(separator) = $choices.env_separator.as_deref() {
env_source = env_source.separator(separator);
}
builder = builder.add_source(env_source);
}
builder
}};
}
impl Assembler {
pub fn make_sync_builder(choices: &AssemblerChoices) -> ConfigBuilder<DefaultState> {
bootstrap_builder!(ConfigBuilder::<DefaultState>::default(), choices)
}
pub fn make_async_builder(choices: &AssemblerChoices) -> ConfigBuilder<AsyncState> {
bootstrap_builder!(ConfigBuilder::<AsyncState>::default(), choices)
}
}