use crate::{
checkers::{base::CheckDefinitionError, file::FileCheck},
mapping::generic::Mapping,
};
use super::super::{
GenericChecker,
base::{CheckConstructor, CheckError, Checker},
};
#[derive(Debug)]
pub(crate) struct KeyAbsent {
file_check: FileCheck,
value: toml_edit::Table,
}
impl CheckConstructor for KeyAbsent {
type Output = Self;
fn from_check_table(
generic_check: GenericChecker,
check_table: toml_edit::Table,
) -> Result<Self::Output, CheckDefinitionError> {
let file_check = FileCheck::from_check_table(generic_check, &check_table)?;
let key_absent = match check_table.get("key") {
None => {
return Err(CheckDefinitionError::InvalidDefinition(
"`key` key is not present".into(),
));
}
Some(absent) => match absent.as_table() {
None => {
return Err(CheckDefinitionError::InvalidDefinition(
"`key` is not a table".into(),
));
}
Some(absent) => {
absent.clone()
}
},
};
Ok(Self {
file_check,
value: key_absent,
})
}
}
impl Checker for KeyAbsent {
fn checker_type(&self) -> String {
"key_absent".to_string()
}
fn generic_checker(&self) -> &GenericChecker {
&self.file_check.generic_check
}
fn checker_object(&self) -> String {
self.file_check.check_object()
}
fn check_(&self, fix: bool) -> Result<crate::checkers::base::CheckResult, CheckError> {
let mut doc = self.file_check.get_mapping()?;
unset_key(doc.as_mut(), &self.value);
self.file_check.conclude_check_with_new_doc(doc, fix)
}
}
fn unset_key(doc: &mut dyn Mapping, table_to_unset: &dyn toml_edit::TableLike) {
for (key_to_unset, value_to_unset) in table_to_unset.iter() {
if let Some(child_table_to_unset) = value_to_unset.as_table_like() {
if child_table_to_unset.is_empty() {
doc.remove(key_to_unset);
} else if let Ok(child_doc) = doc.get_mapping(key_to_unset, false) {
unset_key(child_doc, child_table_to_unset);
} else {
log::info!(
"Key {key_to_unset} is not found in toml, so we can not remove that key",
);
}
}
}
}
#[cfg(test)]
mod tests {
use crate::checkers::test_helpers::read_test_files;
use super::*;
#[test]
fn test_test_files() {
for (test_path, test_input, test_expected_output, checker) in read_test_files("key_absent")
{
let mut test_input = test_input;
unset_key(test_input.as_mut(), &checker);
assert_eq!(
*test_expected_output,
test_input.to_string(4).unwrap(),
"test_path {test_path} failed"
);
}
}
}