From dd8a8207ce46de8a0332dd8e6947d9480d5c192e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 23 Sep 2023 19:35:12 -0400 Subject: [PATCH] Move assert bounds for elements and objects (except PlainText) to the compare element/object functions. --- src/compare/diff.rs | 49 +++++++++++++++++++++++++++++++++++++-------- src/compare/util.rs | 4 ++-- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 9951911..17156b1 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -315,9 +315,9 @@ fn compare_element<'s>( Element::BabelCall(obj) => compare_babel_call(source, emacs, obj), Element::LatexEnvironment(obj) => compare_latex_environment(source, emacs, obj), }; - match compare_result { - Ok(_) => compare_result, - Err(ref e) => Ok(DiffResult { + + let mut compare_result = match compare_result.unwrap_or_else(|e| { + DiffResult { status: DiffStatus::Bad, name: "error!".to_owned(), message: Some(e.to_string()), @@ -325,8 +325,23 @@ fn compare_element<'s>( rust_source: rust.get_standard_properties().get_source(), emacs_token: emacs, } - .into()), + .into() + }) { + DiffEntry::DiffResult(inner) => inner, + DiffEntry::DiffLayer(_) => { + unreachable!("Layers are only interior to DiffResults of AST nodes.") + } + }; + + match assert_bounds(source, emacs, rust.get_standard_properties()) { + Err(err) => { + compare_result.status = DiffStatus::Bad; + compare_result.message = Some(err.to_string()) + } + Ok(_) => {} } + + Ok(compare_result.into()) } fn compare_object<'s>( @@ -363,9 +378,8 @@ fn compare_object<'s>( Object::Superscript(obj) => compare_superscript(source, emacs, obj), Object::Timestamp(obj) => compare_timestamp(source, emacs, obj), }; - match compare_result { - Ok(_) => compare_result, - Err(ref e) => Ok(DiffResult { + let mut compare_result = match compare_result.unwrap_or_else(|e| { + DiffResult { status: DiffStatus::Bad, name: "error!".to_owned(), message: Some(e.to_string()), @@ -373,8 +387,27 @@ fn compare_object<'s>( rust_source: rust.get_standard_properties().get_source(), emacs_token: emacs, } - .into()), + .into() + }) { + DiffEntry::DiffResult(inner) => inner, + DiffEntry::DiffLayer(_) => { + unreachable!("Layers are only interior to DiffResults of AST nodes.") + } + }; + + // PlainText is a special case because upstream Org-Mode uses relative values for the bounds in plaintext rather than absolute so the below checks do not account for that. + if let Object::PlainText(_) = rust { + } else { + match assert_bounds(source, emacs, rust.get_standard_properties()) { + Err(err) => { + compare_result.status = DiffStatus::Bad; + compare_result.message = Some(err.to_string()) + } + Ok(_) => {} + } } + + Ok(compare_result.into()) } pub fn compare_document<'s>( diff --git a/src/compare/util.rs b/src/compare/util.rs index 1804cd9..3bebf2c 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -13,7 +13,7 @@ fn is_slice_of(parent: &str, child: &str) -> bool { /// Get the byte offset into source that the rust object exists at. /// /// These offsets are zero-based unlike the elisp ones. -fn get_rust_byte_offsets<'s, S: StandardProperties<'s>>( +fn get_rust_byte_offsets<'s, S: StandardProperties<'s> + ?Sized>( original_document: &'s str, rust_ast_node: &'s S, ) -> (usize, usize) { @@ -46,7 +46,7 @@ pub(crate) fn assert_name<'s>( /// Assert that the character ranges defined by upstream org-mode's :standard-properties match the slices in Organic's StandardProperties. /// /// This does **not** handle plain text because plain text is a special case. -pub(crate) fn assert_bounds<'s, S: StandardProperties<'s>>( +pub(crate) fn assert_bounds<'s, S: StandardProperties<'s> + ?Sized>( original_document: &'s str, emacs: &'s Token<'s>, rust: &'s S,