use globetrotter_model::{self as model, diagnostics::Spanned};
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub struct SettingsLayer {
pub strict: Option<bool>,
pub check_templates: Option<bool>,
pub dry_run: Option<bool>,
pub print_absolute_paths: Option<bool>,
pub template_engine: Option<Spanned<model::TemplateEngine>>,
}
#[expect(
clippy::struct_excessive_bools,
reason = "independent settled on/off settings, not a state machine"
)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Settings {
pub strict: bool,
pub check_templates: bool,
pub dry_run: bool,
pub print_absolute_paths: bool,
pub template_engine: Option<Spanned<model::TemplateEngine>>,
}
impl Settings {
#[must_use]
pub fn resolve(config: &SettingsLayer, overrides: &SettingsLayer) -> Self {
Self {
strict: overrides.strict.or(config.strict).unwrap_or(true),
check_templates: overrides
.check_templates
.or(config.check_templates)
.unwrap_or(true),
dry_run: overrides.dry_run.or(config.dry_run).unwrap_or(false),
print_absolute_paths: overrides
.print_absolute_paths
.or(config.print_absolute_paths)
.unwrap_or(false),
template_engine: overrides
.template_engine
.clone()
.or_else(|| config.template_engine.clone()),
}
}
}
#[cfg(test)]
mod tests {
use super::{Settings, SettingsLayer};
use globetrotter_model::{TemplateEngine, diagnostics::Spanned};
use similar_asserts::assert_eq as sim_assert_eq;
#[test_util::test]
fn defaults_apply_when_no_layer_specifies_a_value() {
let settings = Settings::resolve(&SettingsLayer::default(), &SettingsLayer::default());
sim_assert_eq!(
have: settings,
want: Settings {
strict: true,
check_templates: true,
dry_run: false,
print_absolute_paths: false,
template_engine: None,
}
);
}
#[test_util::test]
fn config_layer_is_reachable_without_overrides() {
let config = SettingsLayer {
strict: Some(false),
check_templates: Some(false),
dry_run: Some(true),
print_absolute_paths: Some(true),
template_engine: Some(Spanned::dummy(TemplateEngine::Jinja2)),
};
let settings = Settings::resolve(&config, &SettingsLayer::default());
sim_assert_eq!(
have: settings,
want: Settings {
strict: false,
check_templates: false,
dry_run: true,
print_absolute_paths: true,
template_engine: Some(Spanned::dummy(TemplateEngine::Jinja2)),
}
);
}
#[test_util::test]
fn overrides_win_over_config_in_both_directions() {
let config = SettingsLayer {
strict: Some(true),
check_templates: Some(true),
dry_run: Some(false),
print_absolute_paths: Some(false),
template_engine: Some(Spanned::dummy(TemplateEngine::Jinja2)),
};
let overrides = SettingsLayer {
strict: Some(false),
check_templates: Some(false),
dry_run: Some(true),
print_absolute_paths: Some(true),
template_engine: Some(Spanned::dummy(TemplateEngine::Handlebars)),
};
let settings = Settings::resolve(&config, &overrides);
sim_assert_eq!(
have: settings,
want: Settings {
strict: false,
check_templates: false,
dry_run: true,
print_absolute_paths: true,
template_engine: Some(Spanned::dummy(TemplateEngine::Handlebars)),
}
);
}
}