Compare macro properties.

This commit is contained in:
Tom Alexander 2023-10-08 14:40:01 -04:00
parent 3f707149e3
commit 1a2f0856da
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 84 additions and 3 deletions

View File

@ -1,6 +1,7 @@
use std::fmt::Debug; use std::fmt::Debug;
use super::diff::DiffStatus; use super::diff::DiffStatus;
use super::sexp::unquote;
use super::sexp::Token; use super::sexp::Token;
use super::util::get_property; use super::util::get_property;
use super::util::get_property_quoted_string; use super::util::get_property_quoted_string;
@ -102,3 +103,57 @@ pub(crate) fn compare_property_unquoted_atom<'b, 's, 'x, R, RG: Fn(R) -> Option<
Ok(None) Ok(None)
} }
} }
pub(crate) fn compare_property_list_of_quoted_string<
'b,
's,
'x,
'y,
R,
RV: AsRef<str> + std::fmt::Debug + 'y,
RG: Fn(R) -> Option<&'y Vec<RV>>,
>(
emacs: &'b Token<'s>,
rust_node: R,
emacs_field: &'x str,
rust_value_getter: RG,
) -> Result<Option<(DiffStatus, Option<String>)>, Box<dyn std::error::Error>> {
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(Some((this_status, message)));
}
(Some(el), Some(rl)) if el.len() != rl.len() => {
let this_status = DiffStatus::Bad;
let message = Some(format!(
"{} mismatch (emacs != rust) {:?} != {:?}",
emacs_field, value, rust_value
));
return Ok(Some((this_status, message)));
}
(Some(el), Some(rl)) => {
for (e, r) in el.iter().zip(rl) {
let e = unquote(e.as_atom()?)?;
let r = r.as_ref();
if e != r {
let this_status = DiffStatus::Bad;
let message = Some(format!(
"{} mismatch (emacs != rust) {:?} != {:?}",
emacs_field, value, rust_value
));
return Ok(Some((this_status, message)));
}
}
}
}
Ok(None)
}

View File

@ -6,6 +6,7 @@ use std::collections::HashSet;
use super::compare_field::compare_identity; use super::compare_field::compare_identity;
use super::compare_field::compare_property_always_nil; use super::compare_field::compare_property_always_nil;
use super::compare_field::compare_property_list_of_quoted_string;
use super::compare_field::compare_property_quoted_string; use super::compare_field::compare_property_quoted_string;
use super::compare_field::compare_property_unquoted_atom; use super::compare_field::compare_property_unquoted_atom;
use super::elisp_fact::ElispFact; use super::elisp_fact::ElispFact;
@ -3068,10 +3069,35 @@ fn compare_org_macro<'b, 's>(
emacs: &'b Token<'s>, emacs: &'b Token<'s>,
rust: &'b OrgMacro<'s>, rust: &'b OrgMacro<'s>,
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> { ) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
let this_status = DiffStatus::Good; let mut this_status = DiffStatus::Good;
let message = None; let mut message = None;
// TODO: Compare :key :value :args if let Some((new_status, new_message)) = compare_properties!(
emacs,
rust,
(
EmacsField::Required(":key"),
|r| Some(r.macro_name),
compare_property_quoted_string
),
(
EmacsField::Required(":value"),
|r| Some(r.source),
compare_property_quoted_string
),
(
EmacsField::Required(":args"),
|r| if r.macro_args.is_empty() {
None
} else {
Some(&r.macro_args)
},
compare_property_list_of_quoted_string
)
)? {
this_status = new_status;
message = new_message;
}
Ok(DiffResult { Ok(DiffResult {
status: this_status, status: this_status,