compare_properties plain list item.

This commit is contained in:
Tom Alexander 2023-10-09 21:54:29 -04:00
parent 409a92333e
commit f543caee00
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
2 changed files with 62 additions and 99 deletions

View File

@ -0,0 +1,3 @@
- [ ] Foo
- [-] Bar
- [X] Baz

View File

@ -83,8 +83,6 @@ use crate::types::Paragraph;
use crate::types::PlainLink;
use crate::types::PlainList;
use crate::types::PlainListItem;
use crate::types::PlainListItemCounter;
use crate::types::PlainListItemPreBlank;
use crate::types::PlainListType;
use crate::types::PlainText;
use crate::types::Planning;
@ -1121,108 +1119,70 @@ fn compare_plain_list_item<'b, 's>(
source: &'s str,
emacs: &'b Token<'s>,
rust: &'b PlainListItem<'s>,
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error>> {
let children = emacs.as_list()?;
let mut child_status = Vec::new();
) -> Result<DiffEntry<'b, 's>, Box<dyn std::error::Error + 's>> {
let mut this_status = DiffStatus::Good;
let mut child_status = Vec::new();
let mut message = None;
// Compare tag
let tag = get_property(emacs, ":tag")?;
match (tag, rust.tag.is_empty()) {
(None, true) => {}
(None, false) | (Some(_), true) => {
this_status = DiffStatus::Bad;
message = Some("Mismatched tags".to_owned());
}
(Some(tag), false) => {
let tag_status = tag
.as_list()?
.iter()
.zip(rust.tag.iter())
.map(|(emacs_child, rust_child)| {
compare_ast_node(source, emacs_child, rust_child.into())
})
.collect::<Result<Vec<_>, _>>()?;
child_status.push(artificial_diff_scope("tag", tag_status)?);
}
};
compare_children(
source,
emacs,
&rust.children,
&mut child_status,
&mut this_status,
&mut message,
)?;
// Compare contents
let contents_status = children
.iter()
.skip(2)
.zip(rust.children.iter())
.map(|(emacs_child, rust_child)| compare_ast_node(source, emacs_child, rust_child.into()))
.collect::<Result<Vec<_>, _>>()?;
child_status.push(artificial_diff_scope("contents", contents_status)?);
// Compare bullet
let bullet = get_property_quoted_string(emacs, ":bullet")?
.ok_or("Plain list items must have a :bullet.")?;
if bullet != rust.bullet {
this_status = DiffStatus::Bad;
message = Some(format!(
"Bullet mismatch (emacs != rust) {:?} != {:?}",
bullet, rust.bullet
));
}
// Compare counter
let counter = get_property_unquoted_atom(emacs, ":counter")?;
let counter: Option<PlainListItemCounter> = counter
.map(|val| val.parse())
.map_or(Ok(None), |r| r.map(Some))?;
match (counter, rust.counter) {
(None, None) => {}
(None, Some(_)) | (Some(_), None) => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Counter mismatch (emacs != rust) {:?} != {:?}",
counter, rust.counter
));
for diff in compare_properties!(
source,
emacs,
rust,
(
EmacsField::Required(":tag"),
|r| if r.tag.is_empty() {
None
} else {
Some(r.tag.iter())
},
compare_property_list_of_ast_nodes
),
(
EmacsField::Required(":bullet"),
|r| Some(r.bullet),
compare_property_quoted_string
),
(
EmacsField::Required(":counter"),
|r| r.counter,
compare_property_numeric
),
(
EmacsField::Required(":checkbox"),
|r| r
.checkbox
.as_ref()
.map(|(checkbox_type, _)| checkbox_type)
.map(|checkbox_type| match checkbox_type {
CheckboxType::On => "on",
CheckboxType::Trans => "trans",
CheckboxType::Off => "off",
}),
compare_property_unquoted_atom
),
(
EmacsField::Required(":pre-blank"),
|r| Some(r.pre_blank),
compare_property_numeric
)
) {
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),
}
(Some(e), Some(r)) if e != r => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Counter mismatch (emacs != rust) {:?} != {:?}",
counter, rust.counter
));
}
(Some(_), Some(_)) => {}
};
// Compare checkbox
let checkbox = get_property(emacs, ":checkbox")?
.map(Token::as_atom)
.map_or(Ok(None), |r| r.map(Some))?
.unwrap_or("nil");
match (checkbox, &rust.checkbox) {
("nil", None) => {}
("off", Some((CheckboxType::Off, _))) => {}
("trans", Some((CheckboxType::Trans, _))) => {}
("on", Some((CheckboxType::On, _))) => {}
_ => {
this_status = DiffStatus::Bad;
message = Some(format!(
"Checkbox mismatch (emacs != rust) {:?} != {:?}",
checkbox, rust.checkbox
));
}
};
// Compare pre-blank
// :pre-blank appears to count the line breaks between "::" and the contents in a descriptive list. Oddly enough it does not count the spaces so I'm not quite sure what the value is.
let pre_blank = get_property_unquoted_atom(emacs, ":pre-blank")?;
let pre_blank: Option<PlainListItemPreBlank> = pre_blank
.map(|val| val.parse())
.map_or(Ok(None), |r| r.map(Some))?;
if pre_blank.unwrap_or(0) != rust.pre_blank {
this_status = DiffStatus::Bad;
message = Some(format!(
"Pre-blank mismatch (emacs != rust) {:?} != {:?}",
pre_blank, rust.pre_blank
));
}
Ok(DiffResult {