Compare heading tags.
Some checks failed
rust-test Build rust-test has failed
rust-build Build rust-build has succeeded

This commit is contained in:
Tom Alexander
2023-08-25 06:46:00 -04:00
parent be6197e4c7
commit 9cc5e63c1b
2 changed files with 81 additions and 41 deletions

View File

@@ -1,3 +1,5 @@
use std::collections::HashSet;
use super::util::assert_bounds;
use super::util::assert_name;
use crate::parser::sexp::Token;
@@ -58,6 +60,7 @@ use crate::parser::Timestamp;
use crate::parser::Underline;
use crate::parser::Verbatim;
use crate::parser::VerseBlock;
use crate::parser::sexp::unquote;
#[derive(Debug)]
pub struct DiffResult {
@@ -323,6 +326,7 @@ fn compare_heading<'s>(
let children = emacs.as_list()?;
let mut child_status = Vec::new();
let mut this_status = DiffStatus::Good;
let mut message = None;
let emacs_name = "headline";
if assert_name(emacs, emacs_name).is_err() {
this_status = DiffStatus::Bad;
@@ -347,8 +351,19 @@ fn compare_heading<'s>(
for (emacs_child, rust_child) in title.as_list()?.iter().zip(rust.title.iter()) {
child_status.push(compare_object(source, emacs_child, rust_child)?);
}
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(", ")));
}
// TODO: Compare tags, todo-keyword, level, priority
// TODO: Compare todo-keyword, level, priority
for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) {
match rust_child {
@@ -364,11 +379,38 @@ fn compare_heading<'s>(
Ok(DiffResult {
status: this_status,
name: emacs_name.to_owned(),
message: None,
message,
children: child_status,
})
}
fn get_tags_from_heading<'s>(
emacs: &'s Token<'s>,
) -> Result<HashSet<String>, Box<dyn std::error::Error>> {
let children = emacs.as_list()?;
let attributes_child = children
.iter()
.nth(1)
.ok_or("Should have an attributes child.")?;
let attributes_map = attributes_child.as_map()?;
let tags = attributes_map
.get(":tags")
.ok_or("Missing :tags attribute.")?;
match tags.as_atom() {
Ok("nil") => {
return Ok(HashSet::new());
}
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<'s>(
source: &'s str,
emacs: &'s Token<'s>,
@@ -1027,7 +1069,7 @@ fn compare_plain_text<'s>(
rust.source.len()
));
}
let unquoted_text = text.unquote()?;
let unquoted_text = unquote(text.text)?;
if unquoted_text != rust.source {
this_status = DiffStatus::Bad;
message = Some(format!(