From d1ef83afca011c5f99ba494cd8b7c95cf7f045cb Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Mon, 9 Oct 2023 19:51:31 -0400 Subject: [PATCH] Compare properties of subscript and superscript. --- src/compare/diff.rs | 76 +++++++++++++++++++++---- src/parser/subscript_and_superscript.rs | 21 ++++++- src/types/object.rs | 4 ++ 3 files changed, 89 insertions(+), 12 deletions(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 733ce7f..b79d8ca 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -3823,20 +3823,48 @@ fn compare_statistics_cookie<'b, 's>( } fn compare_subscript<'b, 's>( - _source: &'s str, + source: &'s str, emacs: &'b Token<'s>, rust: &'b Subscript<'s>, ) -> Result, Box> { - let this_status = DiffStatus::Good; - let message = None; + let mut this_status = DiffStatus::Good; + let mut child_status = Vec::new(); + let mut message = None; - // TODO: Compare :use-brackets-p + compare_children( + source, + emacs, + &rust.children, + &mut child_status, + &mut this_status, + &mut message, + )?; + + for diff in compare_properties!( + source, + emacs, + rust, + ( + EmacsField::Required(":use-brackets-p"), + |r| r.use_brackets, + compare_property_boolean + ) + ) { + match diff { + ComparePropertiesResult::NoChange => {} + ComparePropertiesResult::SelfChange(new_status, new_message) => { + this_status = new_status; + message = new_message + } + ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry), + } + } Ok(DiffResult { status: this_status, name: rust.get_elisp_name(), message, - children: Vec::new(), + children: child_status, rust_source: rust.get_source(), emacs_token: emacs, } @@ -3844,20 +3872,48 @@ fn compare_subscript<'b, 's>( } fn compare_superscript<'b, 's>( - _source: &'s str, + source: &'s str, emacs: &'b Token<'s>, rust: &'b Superscript<'s>, ) -> Result, Box> { - let this_status = DiffStatus::Good; - let message = None; + let mut this_status = DiffStatus::Good; + let mut child_status = Vec::new(); + let mut message = None; - // TODO: Compare :use-brackets-p + compare_children( + source, + emacs, + &rust.children, + &mut child_status, + &mut this_status, + &mut message, + )?; + + for diff in compare_properties!( + source, + emacs, + rust, + ( + EmacsField::Required(":use-brackets-p"), + |r| r.use_brackets, + compare_property_boolean + ) + ) { + match diff { + ComparePropertiesResult::NoChange => {} + ComparePropertiesResult::SelfChange(new_status, new_message) => { + this_status = new_status; + message = new_message + } + ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry), + } + } Ok(DiffResult { status: this_status, name: rust.get_elisp_name(), message, - children: Vec::new(), + children: child_status, rust_source: rust.get_source(), emacs_token: emacs, } diff --git a/src/parser/subscript_and_superscript.rs b/src/parser/subscript_and_superscript.rs index 5f8c324..0736bc3 100644 --- a/src/parser/subscript_and_superscript.rs +++ b/src/parser/subscript_and_superscript.rs @@ -30,6 +30,7 @@ use crate::error::MyError; use crate::error::Res; use crate::parser::util::get_consumed; use crate::types::Object; +use crate::types::PlainText; use crate::types::Subscript; use crate::types::Superscript; @@ -57,14 +58,22 @@ pub(crate) fn subscript<'b, 'g, 'r, 's>( // We check for the underscore first before checking the pre-character as a minor optimization to avoid walking up the context tree to find the document root unnecessarily. let (remaining, _) = tag("_")(input)?; pre(input)?; - let (remaining, _body) = script_body(context, remaining)?; + let (remaining, body) = script_body(context, remaining)?; let (remaining, _trailing_whitespace) = maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?; let source = get_consumed(input, remaining); + + let (use_brackets, body) = match body { + ScriptBody::Braceless(text) => (false, vec![Object::PlainText(PlainText { source: text })]), + ScriptBody::WithBraces(body) => (true, body), + }; + Ok(( remaining, Subscript { source: source.into(), + use_brackets, + children: body, }, )) } @@ -80,14 +89,22 @@ pub(crate) fn superscript<'b, 'g, 'r, 's>( // We check for the circumflex first before checking the pre-character as a minor optimization to avoid walking up the context tree to find the document root unnecessarily. let (remaining, _) = tag("^")(input)?; pre(input)?; - let (remaining, _body) = script_body(context, remaining)?; + let (remaining, body) = script_body(context, remaining)?; let (remaining, _trailing_whitespace) = maybe_consume_object_trailing_whitespace_if_not_exiting(context, remaining)?; let source = get_consumed(input, remaining); + + let (use_brackets, body) = match body { + ScriptBody::Braceless(text) => (false, vec![Object::PlainText(PlainText { source: text })]), + ScriptBody::WithBraces(body) => (true, body), + }; + Ok(( remaining, Superscript { source: source.into(), + use_brackets, + children: body, }, )) } diff --git a/src/types/object.rs b/src/types/object.rs index 2ce3f50..5d2f1dd 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -252,11 +252,15 @@ pub struct StatisticsCookie<'s> { #[derive(Debug, PartialEq)] pub struct Subscript<'s> { pub source: &'s str, + pub use_brackets: bool, + pub children: Vec>, } #[derive(Debug, PartialEq)] pub struct Superscript<'s> { pub source: &'s str, + pub use_brackets: bool, + pub children: Vec>, } #[derive(Debug, PartialEq, Clone)]