From 31f69141947e7b59792c5da8fa6b5b6030f66a54 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 15 Apr 2023 18:00:34 -0400 Subject: [PATCH] Add code to compare drawers. --- src/compare/diff.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 9c32da98..0a0dd08c 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -11,6 +11,7 @@ use crate::parser::Paragraph; use crate::parser::PlainList; use crate::parser::PlainListItem; use crate::parser::Section; +use crate::parser::Drawer; #[derive(Debug)] pub struct DiffResult { @@ -218,7 +219,7 @@ fn compare_element<'s>( Element::GreaterBlock(obj) => compare_greater_block(source, emacs, obj), Element::FootnoteDefinition(obj) => compare_footnote_definition(source, emacs, obj), Element::Comment(obj) => compare_comment(source, emacs, obj), - Element::Drawer(obj) => todo!(), + Element::Drawer(obj) => compare_drawer(source, emacs, obj), } } @@ -497,3 +498,48 @@ fn compare_comment<'s>( children: child_status, }) } + +fn compare_drawer<'s>( + source: &'s str, + emacs: &'s Token<'s>, + rust: &'s Drawer<'s>, +) -> Result> { + let children = emacs.as_list()?; + let first_child = children + .first() + .ok_or("Should have at least one child.")? + .as_atom()?; + if first_child != "drawer" { + return Err("Drawer should correspond to a drawer cell.".into()); + } + let mut child_status = Vec::new(); + let mut this_status = DiffStatus::Good; + + let attributes_child = children + .iter() + .nth(1) + .ok_or("Should have an attributes child.")?; + let attributes_map = attributes_child.as_map()?; + let begin = attributes_map + .get(":begin") + .ok_or("Missing :begin attribute.")? + .as_atom()?; + let end = attributes_map + .get(":end") + .ok_or("Missing :end attribute.")? + .as_atom()?; + let (rust_begin, rust_end) = get_offsets(source, rust); + if (rust_begin + 1).to_string() != begin || (rust_end + 1).to_string() != end { + this_status = DiffStatus::Bad; + } + + for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { + child_status.push(compare_element(source, emacs_child, rust_child)?); + } + + Ok(DiffResult { + status: this_status, + name: "drawer".to_owned(), + children: child_status, + }) +}