From 7cb71a5a0a524e7035d64568fa9470c7debb1a34 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Tue, 10 Oct 2023 17:40:27 -0400 Subject: [PATCH] Compare the additional properties on headlines. --- src/compare/compare_field.rs | 20 ++++++++++++++++++++ src/compare/diff.rs | 18 +++++++++++++++++- src/compare/util.rs | 26 ++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/compare/compare_field.rs b/src/compare/compare_field.rs index 030da71..3d0daad 100644 --- a/src/compare/compare_field.rs +++ b/src/compare/compare_field.rs @@ -32,6 +32,26 @@ pub(crate) enum ComparePropertiesResult<'b, 's> { DiffEntry(DiffEntry<'b, 's>), } +impl<'b, 's> ComparePropertiesResult<'b, 's> { + pub(crate) fn apply( + self, + child_status: &mut Vec>, + this_status: &mut DiffStatus, + message: &mut Option, + ) { + match self { + ComparePropertiesResult::NoChange => {} + ComparePropertiesResult::SelfChange(new_status, new_message) => { + *this_status = new_status; + *message = new_message + } + ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry), + } + + // foo + } +} + /// Do no comparison. /// /// This is for when you want to acknowledge that a field exists in the emacs token, but you do not have any validation for it when using the compare_properties!() macro. Ideally, this should be kept to a minimum since this represents untested values. diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 79f3667..e1996a5 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -21,6 +21,7 @@ use super::elisp_fact::GetElispFact; use super::sexp::unquote; use super::sexp::Token; use super::util::assert_no_children; +use super::util::compare_additional_properties; use super::util::compare_children; use super::util::compare_children_iter; use super::util::compare_standard_properties; @@ -537,12 +538,27 @@ fn compare_heading<'b, 's>( let mut child_status = Vec::new(); let mut message = None; - // TODO: Add checks to compare values for additional properties. let additional_property_names: Vec = rust .get_additional_properties() .map(|node_property| format!(":{}", node_property.property_name.to_uppercase())) .collect(); + let additional_properties: Vec<(String, &str)> = rust + .get_additional_properties() + .map(|node_property| { + ( + format!(":{}", node_property.property_name.to_uppercase()), + node_property.value.unwrap_or(""), + ) + }) + .collect(); + + compare_additional_properties(emacs, additional_properties.into_iter())?.apply( + &mut child_status, + &mut this_status, + &mut message, + ); + compare_children( source, emacs, diff --git a/src/compare/util.rs b/src/compare/util.rs index 23099aa..4a4e684 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -1,5 +1,6 @@ use std::str::FromStr; +use super::compare_field::ComparePropertiesResult; use super::diff::DiffEntry; use super::diff::DiffStatus; use super::elisp_fact::GetElispFact; @@ -311,3 +312,28 @@ pub(crate) fn assert_no_children<'b, 's>( } Ok(()) } + +pub(crate) fn compare_additional_properties<'b, 's, RK, RV, RI>( + emacs: &'b Token<'s>, + rust_children: RI, +) -> Result, Box> +where + RK: AsRef, + RV: AsRef, + RI: Iterator + ExactSizeIterator, +{ + for (rust_key, rust_value) in rust_children { + let rust_key = rust_key.as_ref(); + let rust_value = rust_value.as_ref(); + let emacs_value = get_property_quoted_string(emacs, rust_key)?; + if Some(rust_value) != emacs_value.as_ref().map(String::as_str) { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}", + rust_key, emacs_value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + } + Ok(ComparePropertiesResult::NoChange) +}