use crate::config_error::ConfigError;
use crate::config_schema::{MarkdownAutofixOptions, MarkdownRule, PolicyConfig, markdown_rule_from_name};
use crate::config_values::{member_keys, member_path, strings, wrong_kind};
use monochromatic_jsonc_edit::JsoncValue;
fn markdown_rules(value: &JsoncValue, path: &str) -> Result<Vec<MarkdownRule>, ConfigError> {
let names: Vec<String> = strings(value, path)?;
if names.is_empty() {
return Err(ConfigError::new(
format!(
"Configuration key {path} must name at least one rule; set the policy's \
severity to \"off\" to disable it."
)
.as_str(),
));
}
let mut rules: Vec<MarkdownRule> = Vec::<MarkdownRule>::with_capacity(names.len());
for (index, name) in names.iter().enumerate() {
let element_path: String = format!("{path}[{index}]");
let Some(rule) = markdown_rule_from_name(name.as_str()) else {
return Err(ConfigError::new(
format!(
"Configuration key {element_path} names an unknown Markdown rule {name:?}; \
the shipped rule is \"lfs-image-url\"."
)
.as_str(),
));
};
if rules.contains(&rule) {
return Err(ConfigError::new(
format!(
"Configuration key {element_path} repeats the Markdown rule {name:?}; \
list each rule once."
)
.as_str(),
));
}
rules.push(rule);
}
return Ok(rules);
}
pub fn markdown_autofix_options(
value: &JsoncValue,
path: &str,
) -> Result<MarkdownAutofixOptions, ConfigError> {
let Some(entries) = value.entries() else {
return Err(wrong_kind(value, path, "an options object"));
};
let keys: Vec<String> = member_keys(entries, path)?;
let mut options: MarkdownAutofixOptions = PolicyConfig::defaults().markdown_autofix;
for (index, key) in keys.iter().enumerate() {
let key_path: String = member_path(path, key.as_str());
let member: &JsoncValue = &entries[index].value;
if key == "rules" {
options.rules = markdown_rules(member, key_path.as_str())?;
} else if key == "exclude" {
options.exclude = strings(member, key_path.as_str())?;
} else if key == "command" {
return Err(ConfigError::new(
format!(
"Configuration key {key_path} is retired: monochromatic-git-policy-cli runs its own coordinated \
Markdown linter and configuration cannot select a command. Remove the key."
)
.as_str(),
));
} else {
return Err(ConfigError::new(
format!("Unknown configuration key: {key_path}. Accepted options: rules, exclude.")
.as_str(),
));
}
}
return Ok(options);
}