diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 9e3cf05..9550869 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -37,7 +37,6 @@ use crate::types::AstNode; use crate::types::BabelCall; use crate::types::Bold; use crate::types::CenterBlock; -use crate::types::CharOffsetInLine; use crate::types::CheckboxType; use crate::types::Citation; use crate::types::CitationReference; @@ -74,7 +73,6 @@ use crate::types::Keyword; use crate::types::LatexEnvironment; use crate::types::LatexFragment; use crate::types::LineBreak; -use crate::types::LineNumber; use crate::types::LinkType; use crate::types::Minute; use crate::types::MinuteInner; @@ -97,7 +95,6 @@ use crate::types::RadioTarget; use crate::types::RegularLink; use crate::types::RepeaterType; use crate::types::RepeaterWarningDelayValueType; -use crate::types::RetainLabels; use crate::types::Section; use crate::types::SpecialBlock; use crate::types::SrcBlock; @@ -106,7 +103,6 @@ use crate::types::StatisticsCookie; use crate::types::StrikeThrough; use crate::types::Subscript; use crate::types::Superscript; -use crate::types::SwitchNumberLines; use crate::types::Table; use crate::types::TableCell; use crate::types::TableRow; @@ -2085,194 +2081,83 @@ fn compare_export_block<'b, 's>( } fn compare_src_block<'b, 's>( - _source: &'s str, + source: &'s str, emacs: &'b Token<'s>, rust: &'b SrcBlock<'s>, ) -> Result, Box> { let mut this_status = DiffStatus::Good; + let mut child_status = Vec::new(); let mut message = None; - // TODO: Compare :caption - // Compare name - let name = get_property_quoted_string(emacs, ":name")?; - if name.as_ref().map(String::as_str) != rust.name { - this_status = DiffStatus::Bad; - message = Some(format!( - "Name mismatch (emacs != rust) {:?} != {:?}", - name, rust.name - )); - } + assert_no_children(emacs, &mut this_status, &mut message)?; - // Compare language - let language = get_property_quoted_string(emacs, ":language")?; - if language.as_ref().map(String::as_str) != rust.language { - this_status = DiffStatus::Bad; - message = Some(format!( - "Language mismatch (emacs != rust) {:?} != {:?}", - language, rust.language - )); - } - - // Compare value - let contents = get_property_quoted_string(emacs, ":value")?.unwrap_or(String::new()); - if contents != rust.contents { - this_status = DiffStatus::Bad; - message = Some(format!( - "Value mismatch (emacs != rust) {:?} != {:?}", - contents, rust.contents - )); - } - - // Compare switches - let switches = get_property_quoted_string(emacs, ":switches")?; - match (switches.as_ref().map(String::as_str), rust.switches) { - (None, None) => {} - (Some(""), None) => {} - (None, Some("")) => { - unreachable!("The organic parser would return a None instead of an empty string."); - } - (Some(e), Some(r)) if e == r => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Switches mismatch (emacs != rust) {:?} != {:?}", - switches, rust.switches - )); - } - } - - // Compare parameters - let parameters = get_property_quoted_string(emacs, ":parameters")?; - match (parameters.as_ref().map(String::as_str), rust.parameters) { - (None, None) => {} - (Some(""), None) => {} - (None, Some("")) => { - unreachable!("The organic parser would return a None instead of an empty string."); - } - (Some(e), Some(r)) if e == r => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Parameters mismatch (emacs != rust) {:?} != {:?}", - parameters, rust.parameters - )); - } - } - - // Compare number-lines - let number_lines = get_property(emacs, ":number-lines")?; - match (number_lines, &rust.number_lines) { - (None, None) => {} - (Some(number_lines), Some(rust_number_lines)) => { - let token_list = number_lines.as_list()?; - let number_type = token_list - .get(0) - .map(Token::as_atom) - .map_or(Ok(None), |r| r.map(Some))? - .ok_or(":number-lines should have a type.")?; - let number_value = token_list - .get(2) - .map(Token::as_atom) - .map_or(Ok(None), |r| r.map(Some))? - .map(|val| val.parse::()) - .map_or(Ok(None), |r| r.map(Some))? - .ok_or(":number-lines should have a value.")?; - match (number_type, number_value, rust_number_lines) { - ("new", emacs_val, SwitchNumberLines::New(rust_val)) if emacs_val == *rust_val => {} - ("continued", emacs_val, SwitchNumberLines::Continued(rust_val)) - if emacs_val == *rust_val => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Number lines mismatch (emacs != rust) {:?} != {:?}", - number_lines, rust.number_lines - )); - } + for diff in compare_properties!( + source, + emacs, + rust, + ( + EmacsField::Optional(":name"), + |r| r.name, + compare_property_quoted_string + ), + ( + EmacsField::Optional(":caption"), + compare_identity, + compare_noop + ), + ( + EmacsField::Required(":language"), + |r| r.language, + compare_property_quoted_string + ), + ( + EmacsField::Required(":value"), + |r| Some(r.contents.as_str()), + compare_property_quoted_string + ), + ( + EmacsField::Required(":switches"), + |r| r.switches, + compare_property_quoted_string + ), + ( + EmacsField::Required(":parameters"), + |r| r.parameters, + compare_property_quoted_string + ), + ( + EmacsField::Required(":number-lines"), + |r| r.number_lines.as_ref(), + compare_property_number_lines + ), + ( + EmacsField::Required(":preserve-indent"), + |r| r.preserve_indent, + compare_property_numeric + ), + ( + EmacsField::Required(":retain-labels"), + |r| &r.retain_labels, + compare_property_retain_labels + ), + ( + EmacsField::Required(":use-labels"), + |r| r.use_labels, + compare_property_boolean + ), + ( + EmacsField::Required(":label-fmt"), + |r| r.label_format, + compare_property_quoted_string + ) + ) { + match diff { + ComparePropertiesResult::NoChange => {} + ComparePropertiesResult::SelfChange(new_status, new_message) => { + this_status = new_status; + message = new_message } - } - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Number lines mismatch (emacs != rust) {:?} != {:?}", - number_lines, rust.number_lines - )); - } - }; - - // Compare preserve-indent - let preserve_indent: Option = - get_property_numeric(emacs, ":preserve-indent")?; - if preserve_indent != rust.preserve_indent { - this_status = DiffStatus::Bad; - message = Some(format!( - "Prserve indent mismatch (emacs != rust) {:?} != {:?}", - preserve_indent, rust.preserve_indent - )); - } - - // Compare retain-labels - // retain-labels is t by default, nil if -r is set, or a number if -k and -r is set. - let retain_labels = get_property_unquoted_atom(emacs, ":retain-labels")?; - if let Some(retain_labels) = retain_labels { - if retain_labels == "t" { - match rust.retain_labels { - RetainLabels::Yes => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Retain labels mismatch (emacs != rust) {:?} != {:?}", - retain_labels, rust.retain_labels - )); - } - } - } else { - let retain_labels: CharOffsetInLine = get_property_numeric(emacs, ":retain-labels")?.expect("Cannot be None or else the earlier get_property_unquoted_atom would have been None."); - match (retain_labels, &rust.retain_labels) { - (e, RetainLabels::Keep(r)) if e == *r => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Retain labels mismatch (emacs != rust) {:?} != {:?}", - retain_labels, rust.retain_labels - )); - } - } - } - } else { - match rust.retain_labels { - RetainLabels::No => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Retain labels mismatch (emacs != rust) {:?} != {:?}", - retain_labels, rust.retain_labels - )); - } - } - } - - // Compare use-labels - let use_labels = get_property_boolean(emacs, ":use-labels")?; - if use_labels != rust.use_labels { - this_status = DiffStatus::Bad; - message = Some(format!( - "Use labels mismatch (emacs != rust) {:?} != {:?}", - use_labels, rust.use_labels - )); - } - - // Compare label-fmt - let label_format = get_property_quoted_string(emacs, ":label-fmt")?; - match (label_format.as_ref(), rust.label_format) { - (None, None) => {} - (Some(emacs_label_format), Some(rust_label_format)) - if emacs_label_format == rust_label_format => {} - _ => { - this_status = DiffStatus::Bad; - message = Some(format!( - "Label format mismatch (emacs != rust) {:?} != {:?}", - label_format, rust.label_format - )); + ComparePropertiesResult::DiffEntry(diff_entry) => child_status.push(diff_entry), } } @@ -2280,7 +2165,7 @@ fn compare_src_block<'b, 's>( status: this_status, name: rust.get_elisp_name(), message, - children: Vec::new(), + children: child_status, rust_source: rust.get_source(), emacs_token: emacs, }