use crate::data::Profile;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
#[expect(
clippy::struct_excessive_bools,
reason = "this type is a set of independent switches by design"
)]
pub struct DocumentRules {
pub file_identity: bool,
pub variables: bool,
pub step_tables: bool,
pub nested_steps: bool,
pub flowcharts: bool,
pub link_steps: bool,
pub split_step_groups: bool,
pub engine_callbacks: bool,
pub code_modules: bool,
pub call_hierarchy: bool,
pub plain_title: bool,
pub popup_detail: bool,
}
impl DocumentRules {
#[must_use]
pub const fn for_profile(profile: Profile) -> Self {
match profile {
Profile::Engineer => Self {
file_identity: true,
variables: true,
step_tables: true,
nested_steps: true,
link_steps: false,
flowcharts: false,
split_step_groups: true,
engine_callbacks: true,
code_modules: true,
call_hierarchy: true,
plain_title: true,
popup_detail: true,
},
Profile::Business => Self {
file_identity: false,
variables: false,
step_tables: false,
nested_steps: false,
flowcharts: true,
link_steps: false,
split_step_groups: false,
engine_callbacks: false,
code_modules: false,
call_hierarchy: true,
plain_title: true,
popup_detail: false,
},
Profile::Station => Self {
file_identity: true,
variables: false,
step_tables: false,
nested_steps: false,
flowcharts: false,
link_steps: false,
split_step_groups: false,
engine_callbacks: false,
code_modules: false,
call_hierarchy: false,
plain_title: false,
popup_detail: false,
},
}
}
}
impl Default for DocumentRules {
fn default() -> Self {
Self::for_profile(Profile::Engineer)
}
}
#[cfg(test)]
mod tests {
use super::DocumentRules;
use crate::data::Profile;
#[test]
fn a_profile_is_a_preset_that_can_be_overridden() {
let rules = DocumentRules {
step_tables: true,
..DocumentRules::for_profile(Profile::Business)
};
assert!(rules.step_tables);
assert!(rules.flowcharts, "the rest of the preset is untouched");
assert!(!rules.variables);
}
#[test]
fn each_profile_answers_what_it_shows_without_reading_the_renderer() {
let engineer = DocumentRules::for_profile(Profile::Engineer);
assert!(engineer.step_tables && !engineer.flowcharts);
let business = DocumentRules::for_profile(Profile::Business);
assert!(business.flowcharts && !business.step_tables);
assert!(!business.engine_callbacks && !business.variables);
let station = DocumentRules::for_profile(Profile::Station);
assert!(!station.step_tables && !station.flowcharts);
}
#[test]
fn a_document_never_links_steps_it_does_not_list() {
for profile in [Profile::Engineer, Profile::Business, Profile::Station] {
let rules = DocumentRules::for_profile(profile);
assert!(
!rules.link_steps || rules.step_tables,
"{profile:?} links steps without listing them"
);
}
}
}