Remove the old implementation of comparing headlines.

This commit is contained in:
Tom Alexander 2023-10-10 16:09:57 -04:00
parent 275ed87c3f
commit 3aca01891d
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 2 additions and 295 deletions

View File

@ -2,7 +2,6 @@ use std::borrow::Cow;
// TODO: Update all to use the macro to assert there are no unexpected keys. // TODO: Update all to use the macro to assert there are no unexpected keys.
// TODO: Check all compare funtions for whether they correctly iterate children. // TODO: Check all compare funtions for whether they correctly iterate children.
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::collections::HashSet;
use super::compare_field::compare_identity; use super::compare_field::compare_identity;
use super::compare_field::compare_noop; use super::compare_field::compare_noop;
@ -25,8 +24,6 @@ use super::util::assert_no_children;
use super::util::compare_children; use super::util::compare_children;
use super::util::compare_children_iter; use super::util::compare_children_iter;
use super::util::compare_standard_properties; use super::util::compare_standard_properties;
use super::util::get_property;
use super::util::get_property_boolean;
use super::util::get_property_quoted_string; use super::util::get_property_quoted_string;
use crate::compare::compare_field::ComparePropertiesResult; use crate::compare::compare_field::ComparePropertiesResult;
use crate::compare::compare_field::EmacsField; use crate::compare::compare_field::EmacsField;
@ -48,7 +45,6 @@ use crate::types::Date;
use crate::types::DayOfMonth; use crate::types::DayOfMonth;
use crate::types::DiarySexp; use crate::types::DiarySexp;
use crate::types::Document; use crate::types::Document;
use crate::types::DocumentElement;
use crate::types::Drawer; use crate::types::Drawer;
use crate::types::DynamicBlock; use crate::types::DynamicBlock;
use crate::types::Entity; use crate::types::Entity;
@ -82,7 +78,6 @@ use crate::types::PlainListItem;
use crate::types::PlainListType; use crate::types::PlainListType;
use crate::types::PlainText; use crate::types::PlainText;
use crate::types::Planning; use crate::types::Planning;
use crate::types::PriorityCookie;
use crate::types::PropertyDrawer; use crate::types::PropertyDrawer;
use crate::types::QuoteBlock; use crate::types::QuoteBlock;
use crate::types::RadioLink; use crate::types::RadioLink;
@ -533,7 +528,7 @@ fn compare_section<'b, 's>(
} }
#[allow(dead_code)] #[allow(dead_code)]
fn new_compare_heading<'b, 's>( fn compare_heading<'b, 's>(
source: &'s str, source: &'s str,
emacs: &'b Token<'s>, emacs: &'b Token<'s>,
rust: &'b Heading<'s>, rust: &'b Heading<'s>,
@ -544,7 +539,7 @@ fn new_compare_heading<'b, 's>(
let additional_property_names: Vec<String> = rust let additional_property_names: Vec<String> = rust
.get_additional_properties() .get_additional_properties()
.map(|node_property| format!(":{}", node_property.property_name)) .map(|node_property| format!(":{}", node_property.property_name.to_uppercase()))
.collect(); .collect();
compare_children( compare_children(
@ -671,278 +666,6 @@ fn new_compare_heading<'b, 's>(
.into()) .into())
} }
fn compare_heading<'b, 's>(
source: &'s str,
emacs: &'b Token<'s>,
rust: &'b Heading<'s>,
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
let children = emacs.as_list()?;
let mut child_status = Vec::new();
let mut this_status = DiffStatus::Good;
let mut message = None;
// Compare level
let level = get_property(emacs, ":level")?
.ok_or("Level should not be nil")?
.as_atom()?;
if rust.level.to_string() != level {
this_status = DiffStatus::Bad;
message = Some(format!(
"Headline level do not match (emacs != rust): {} != {}",
level, rust.level
))
}
// Compare tags
let emacs_tags = get_tags_from_heading(emacs)?;
let emacs_tags: HashSet<_> = emacs_tags.iter().map(|val| val.as_str()).collect();
let rust_tags: HashSet<&str> = rust.tags.iter().map(|val| *val).collect();
let difference: Vec<&str> = emacs_tags
.symmetric_difference(&rust_tags)
.map(|val| *val)
.collect();
if !difference.is_empty() {
this_status = DiffStatus::Bad;
message = Some(format!("Mismatched tags: {}", difference.join(", ")));
}
// Compare todo-keyword
let todo_keyword = get_property(emacs, ":todo-keyword")?
.map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))?
.unwrap_or("nil");
match (todo_keyword, &rust.todo_keyword, unquote(todo_keyword)) {
("nil", None, _) => {}
(_, Some((_rust_todo_type, rust_todo)), Ok(emacs_todo)) if emacs_todo == *rust_todo => {}
(emacs_todo, rust_todo, _) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"(emacs != rust) {:?} != {:?}",
emacs_todo, rust_todo
));
}
};
// Compare todo-type
let todo_type = get_property(emacs, ":todo-type")?
.map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))?
.unwrap_or("nil");
// todo-type is an unquoted string either todo, done, or nil
match (todo_type, &rust.todo_keyword) {
("nil", None) => {}
("todo", Some((TodoKeywordType::Todo, _))) => {}
("done", Some((TodoKeywordType::Done, _))) => {}
(emacs_todo, rust_todo) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"(emacs != rust) {:?} != {:?}",
emacs_todo, rust_todo
));
}
};
// Compare title
let title = get_property(emacs, ":title")?;
match (title, rust.title.len()) {
(None, 0) => {}
(None, _) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Titles do not match (emacs != rust): {:?} != {:?}",
title, rust.title
))
}
(Some(title), _) => {
let title_status = title
.as_list()?
.iter()
.zip(rust.title.iter())
.map(|(emacs_child, rust_child)| {
compare_ast_node(source, emacs_child, rust_child.into())
})
.collect::<Result<Vec<_>, _>>()?;
child_status.push(artificial_diff_scope("title", title_status)?);
}
};
// Compare priority
let priority = get_property(emacs, ":priority")?;
match (priority, rust.priority_cookie) {
(None, None) => {}
(None, Some(_)) | (Some(_), None) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Priority cookie mismatch (emacs != rust) {:?} != {:?}",
priority, rust.priority_cookie
));
}
(Some(emacs_priority_cookie), Some(rust_priority_cookie)) => {
let emacs_priority_cookie =
emacs_priority_cookie.as_atom()?.parse::<PriorityCookie>()?;
if emacs_priority_cookie != rust_priority_cookie {
this_status = DiffStatus::Bad;
message = Some(format!(
"Priority cookie mismatch (emacs != rust) {:?} != {:?}",
emacs_priority_cookie, rust_priority_cookie
));
}
}
}
// Compare archived
let archived = get_property(emacs, ":archivedp")?;
match (archived, rust.is_archived) {
(None, true) | (Some(_), false) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"archived mismatch (emacs != rust) {:?} != {:?}",
archived, rust.is_archived
));
}
(None, false) | (Some(_), true) => {}
}
// Compare commented
let commented = get_property(emacs, ":commentedp")?;
match (commented, rust.is_comment) {
(None, true) | (Some(_), false) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"commented mismatch (emacs != rust) {:?} != {:?}",
commented, rust.is_comment
));
}
(None, false) | (Some(_), true) => {}
}
// Compare raw-value
let raw_value = get_property_quoted_string(emacs, ":raw-value")?
.ok_or("Headlines should have :raw-value.")?;
let rust_raw_value = rust.get_raw_value();
if raw_value != rust_raw_value {
this_status = DiffStatus::Bad;
message = Some(format!(
"raw-value mismatch (emacs != rust) {:?} != {:?}",
raw_value, rust_raw_value
));
}
// Compare footnote-section-p
let footnote_section = get_property_boolean(emacs, ":footnote-section-p")?;
if footnote_section != rust.is_footnote_section {
this_status = DiffStatus::Bad;
message = Some(format!(
"footnote section mismatch (emacs != rust) {:?} != {:?}",
footnote_section, rust.is_footnote_section
));
}
// Compare scheduled
let scheduled = get_property(emacs, ":scheduled")?;
match (scheduled, &rust.scheduled) {
(None, None) => {}
(None, Some(_)) | (Some(_), None) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Scheduled mismatch (emacs != rust) {:?} != {:?}",
scheduled, rust.scheduled
));
}
(Some(emacs_child), Some(rust_child)) => {
let result = compare_ast_node(source, emacs_child, rust_child.into())?;
child_status.push(artificial_diff_scope("scheduled", vec![result])?);
}
}
// Compare deadline
let deadline = get_property(emacs, ":deadline")?;
match (deadline, &rust.deadline) {
(None, None) => {}
(None, Some(_)) | (Some(_), None) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Deadline mismatch (emacs != rust) {:?} != {:?}",
deadline, rust.deadline
));
}
(Some(emacs_child), Some(rust_child)) => {
let result = compare_ast_node(source, emacs_child, rust_child.into())?;
child_status.push(artificial_diff_scope("deadline", vec![result])?);
}
}
// Compare closed
let closed = get_property(emacs, ":closed")?;
match (closed, &rust.closed) {
(None, None) => {}
(None, Some(_)) | (Some(_), None) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Closed mismatch (emacs != rust) {:?} != {:?}",
closed, rust.closed
));
}
(Some(emacs_child), Some(rust_child)) => {
let result = compare_ast_node(source, emacs_child, rust_child.into())?;
child_status.push(artificial_diff_scope("closed", vec![result])?);
}
}
// TODO: Compare :pre-blank
// Compare section
let section_status = children
.iter()
.skip(2)
.zip(rust.children.iter())
.map(|(emacs_child, rust_child)| match rust_child {
DocumentElement::Heading(rust_heading) => {
compare_ast_node(source, emacs_child, rust_heading.into())
}
DocumentElement::Section(rust_section) => {
compare_ast_node(source, emacs_child, rust_section.into())
}
})
.collect::<Result<Vec<_>, _>>()?;
child_status.push(artificial_diff_scope("section", section_status)?);
Ok(DiffResult {
status: this_status,
name: rust.get_elisp_name(),
message,
children: child_status,
rust_source: rust.get_source(),
emacs_token: emacs,
}
.into())
}
fn get_tags_from_heading<'b, 's>(
emacs: &'b Token<'s>,
) -> Result<HashSet<String>, Box<dyn std::error::Error>> {
let tags = match get_property(emacs, ":tags")? {
Some(prop) => prop,
None => return Ok(HashSet::new()),
};
match tags.as_atom() {
Ok(val) => panic!("Unexpected value for tags: {:?}", val),
Err(_) => {}
};
let tags = {
let tags = tags.as_list()?;
let strings = tags
.iter()
.map(Token::as_atom)
.collect::<Result<Vec<&str>, _>>()?;
strings
.into_iter()
.map(unquote)
.collect::<Result<HashSet<String>, _>>()?
};
Ok(tags)
}
fn compare_paragraph<'b, 's>( fn compare_paragraph<'b, 's>(
source: &'s str, source: &'s str,
emacs: &'b Token<'s>, emacs: &'b Token<'s>,

View File

@ -221,22 +221,6 @@ pub(crate) fn get_property_quoted_string<'b, 's, 'x>(
.map_or(Ok(None), |r| r.map(Some))?) .map_or(Ok(None), |r| r.map(Some))?)
} }
/// Get a named property containing a boolean value.
///
/// This uses the elisp convention of nil == false, non-nil == true.
///
/// Returns false if key is not found.
pub(crate) fn get_property_boolean<'b, 's, 'x>(
emacs: &'b Token<'s>,
key: &'x str,
) -> Result<bool, Box<dyn std::error::Error>> {
Ok(get_property(emacs, key)?
.map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))?
.unwrap_or("nil")
!= "nil")
}
/// Get a named property containing an unquoted numeric value. /// Get a named property containing an unquoted numeric value.
/// ///
/// Returns None if key is not found. /// Returns None if key is not found.