From 33800c4a88ea59ade69cdfd9f39c958bce47df71 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 16 Oct 2023 12:05:36 -0400 Subject: [PATCH] Implement comparison for optional pair. --- src/compare/compare_field.rs | 101 +++++++++++++++++++++++++++++++++++ src/compare/util.rs | 9 ++++ 2 files changed, 110 insertions(+) diff --git a/src/compare/compare_field.rs b/src/compare/compare_field.rs index 01896aad..3f662e20 100644 --- a/src/compare/compare_field.rs +++ b/src/compare/compare_field.rs @@ -288,6 +288,107 @@ pub(crate) fn compare_property_set_of_quoted_string< Ok(ComparePropertiesResult::NoChange) } +pub(crate) fn compare_property_optional_pair< + 'b, + 's, + 'x, + R, + RV: AsRef + std::fmt::Debug, + ROV: AsRef + std::fmt::Debug, + RG: Fn(R) -> Option<(Option, RV)>, +>( + _source: &'s str, + emacs: &'b Token<'s>, + rust_node: R, + emacs_field: &'x str, + rust_value_getter: RG, +) -> Result, Box> { + let value = get_property(emacs, emacs_field)? + .map(Token::as_list) + .map_or(Ok(None), |r| r.map(Some))?; + let rust_value = rust_value_getter(rust_node); + match (value, &rust_value) { + (None, None) => {} + (None, Some(_)) | (Some(_), None) => { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}", + emacs_field, value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + (Some(el), Some((Some(_), _))) if el.len() != 3 => { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}", + emacs_field, value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + (Some(el), Some((None, _))) if el.len() != 1 => { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}", + emacs_field, value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + (Some(el), Some((Some(orl), rl))) => { + let e = el + .first() + .map(Token::as_atom) + .map_or(Ok(None), |r| r.map(Some))? + .map(unquote) + .map_or(Ok(None), |r| r.map(Some))? + .expect("Above match proved length to be 3."); + let oe = el + .get(2) + .map(Token::as_atom) + .map_or(Ok(None), |r| r.map(Some))? + .map(unquote) + .map_or(Ok(None), |r| r.map(Some))? + .expect("Above match proved length to be 3."); + let r = rl.as_ref(); + let or = orl.as_ref(); + if e != r { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}", + emacs_field, e, r, value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + if oe != or { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}", + emacs_field, e, r, value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + } + (Some(el), Some((None, rl))) => { + let e = el + .first() + .map(Token::as_atom) + .map_or(Ok(None), |r| r.map(Some))? + .map(unquote) + .map_or(Ok(None), |r| r.map(Some))? + .expect("Above match proved length to be 1."); + let r = rl.as_ref(); + if e != r { + let this_status = DiffStatus::Bad; + let message = Some(format!( + "{} mismatch (emacs != rust) {:?} != {:?}. Full list: {:?} != {:?}", + emacs_field, e, r, value, rust_value + )); + return Ok(ComparePropertiesResult::SelfChange(this_status, message)); + } + } + } + Ok(ComparePropertiesResult::NoChange) +} + pub(crate) fn compare_property_boolean<'b, 's, 'x, R, RG: Fn(R) -> bool>( _source: &'s str, emacs: &'b Token<'s>, diff --git a/src/compare/util.rs b/src/compare/util.rs index db160482..f3b26c7b 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -2,6 +2,7 @@ use std::str::FromStr; use super::compare_field::compare_property_list_of_list_of_list_of_ast_nodes; use super::compare_field::compare_property_list_of_quoted_string; +use super::compare_field::compare_property_optional_pair; use super::compare_field::compare_property_quoted_string; use super::compare_field::ComparePropertiesResult; use super::diff::DiffEntry; @@ -377,6 +378,14 @@ where ret.push(diff); } AffiliatedKeywordValue::OptionalPair { optval, val } => { + let diff = compare_property_optional_pair( + source, + emacs, + rust, + emacs_property_name.as_str(), + |_| Some((*optval, *val)), + )?; + ret.push(diff); // todo } AffiliatedKeywordValue::ObjectTree(_) => {