From a4c6e899ac75239bbb1df44972a694d8087c2e5a Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 19 Apr 2023 15:19:21 -0400 Subject: [PATCH] Add a utility function to check the first element in an sexp. --- src/compare/diff.rs | 114 ++++++++++++-------------------------------- src/compare/util.rs | 18 +++++++ 2 files changed, 49 insertions(+), 83 deletions(-) diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 66dfa06..99287dc 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -1,4 +1,5 @@ use super::sexp::Token; +use super::util::assert_name; use crate::compare::util::get_offsets; use crate::parser::Comment; use crate::parser::Document; @@ -18,6 +19,7 @@ use crate::DynamicBlock; pub struct DiffResult { status: DiffStatus, name: String, + message: Option, children: Vec, } @@ -71,11 +73,7 @@ pub fn compare_document<'s>( rust: &'s Document<'s>, ) -> Result> { let children = emacs.as_list()?; - let first_child = children.first().ok_or("Should have at least one child.")?; - let first_child_text = first_child.as_atom()?; - if first_child_text != "org-data" { - return Err("Document should correspond to an org-data cell.".into()); - } + assert_name(emacs, "org-data")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -112,6 +110,7 @@ pub fn compare_document<'s>( Ok(DiffResult { status: this_status, name: "document".to_owned(), + message: None, children: child_status, }) } @@ -122,11 +121,7 @@ fn compare_section<'s>( rust: &'s Section<'s>, ) -> Result> { let children = emacs.as_list()?; - let first_child = children.first().ok_or("Should have at least one child.")?; - let first_child_text = first_child.as_atom()?; - if first_child_text != "section" { - return Err("Section should correspond to a section cell.".into()); - } + assert_name(emacs, "section")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -155,6 +150,7 @@ fn compare_section<'s>( Ok(DiffResult { status: this_status, name: "section".to_owned(), + message: None, children: child_status, }) } @@ -165,11 +161,7 @@ fn compare_heading<'s>( rust: &'s Heading<'s>, ) -> Result> { let children = emacs.as_list()?; - let first_child = children.first().ok_or("Should have at least one child.")?; - let first_child_text = first_child.as_atom()?; - if first_child_text != "headline" { - return Err("Heading should correspond to a headline cell.".into()); - } + assert_name(emacs, "headline")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -205,6 +197,7 @@ fn compare_heading<'s>( Ok(DiffResult { status: this_status, name: "heading".to_owned(), + message: None, children: child_status, }) } @@ -231,13 +224,7 @@ fn compare_paragraph<'s>( rust: &'s Paragraph<'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 != "paragraph" { - return Err("Paragraph should correspond to a paragraph cell.".into()); - } + assert_name(emacs, "paragraph")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -264,6 +251,7 @@ fn compare_paragraph<'s>( Ok(DiffResult { status: this_status, name: "paragraph".to_owned(), + message: None, children: child_status, }) } @@ -274,13 +262,7 @@ fn compare_plain_list<'s>( rust: &'s PlainList<'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 != "plain-list" { - return Err("Paragraph should correspond to a paragraph cell.".into()); - } + assert_name(emacs, "plain-list")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -309,6 +291,7 @@ fn compare_plain_list<'s>( Ok(DiffResult { status: this_status, name: "plain-list".to_owned(), + message: None, children: child_status, }) } @@ -319,13 +302,7 @@ fn compare_plain_list_item<'s>( rust: &'s PlainListItem<'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 != "item" { - return Err("PlainListItem should correspond to an item cell.".into()); - } + assert_name(emacs, "item")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -354,6 +331,7 @@ fn compare_plain_list_item<'s>( Ok(DiffResult { status: this_status, name: "plain-list-item".to_owned(), + message: None, children: child_status, }) } @@ -364,25 +342,14 @@ fn compare_greater_block<'s>( rust: &'s GreaterBlock<'s>, ) -> Result> { let children = emacs.as_list()?; - let first_child = children - .first() - .ok_or("Should have at least one child.")? - .as_atom()?; - match rust.name.to_lowercase().as_str() { - "center" => { - if first_child != "center-block" { - return Err( - "Center greater blocks should correspond to a center-block cell.".into(), - ); - } - } - "quote" => { - if first_child != "quote-block" { - return Err("Quote greater blocks should correspond to a quote-block cell.".into()); - } - } - _ => todo!(), - } + assert_name( + emacs, + match rust.name.to_lowercase().as_str() { + "center" => "center-block", + "quote" => "quote-block", + _ => todo!(), + }, + )?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -411,6 +378,7 @@ fn compare_greater_block<'s>( Ok(DiffResult { status: this_status, name: "greater-block".to_owned(), + message: None, children: child_status, }) } @@ -421,13 +389,7 @@ fn compare_dynamic_block<'s>( rust: &'s DynamicBlock<'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 != "dynamic-block" { - return Err("Dynamic block should correspond to a dynamic-block cell.".into()); - } + assert_name(emacs, "dynamic-block")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -456,6 +418,7 @@ fn compare_dynamic_block<'s>( Ok(DiffResult { status: this_status, name: "dynamic-block".to_owned(), + message: None, children: child_status, }) } @@ -466,13 +429,7 @@ fn compare_footnote_definition<'s>( rust: &'s FootnoteDefinition<'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 != "footnote-definition" { - return Err("Paragraph should correspond to a paragraph cell.".into()); - } + assert_name(emacs, "footnote-definition")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -501,6 +458,7 @@ fn compare_footnote_definition<'s>( Ok(DiffResult { status: this_status, name: "footnote-definition".to_owned(), + message: None, children: child_status, }) } @@ -511,13 +469,7 @@ fn compare_comment<'s>( rust: &'s Comment<'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 != "comment" { - return Err("Comment should correspond to a comment cell.".into()); - } + assert_name(emacs, "comment")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -542,6 +494,7 @@ fn compare_comment<'s>( Ok(DiffResult { status: this_status, name: "comment".to_owned(), + message: None, children: child_status, }) } @@ -552,13 +505,7 @@ fn compare_drawer<'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()); - } + assert_name(emacs, "drawer")?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -587,6 +534,7 @@ fn compare_drawer<'s>( Ok(DiffResult { status: this_status, name: "drawer".to_owned(), + message: None, children: child_status, }) } diff --git a/src/compare/util.rs b/src/compare/util.rs index 1dd9463..2b665e5 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -1,5 +1,7 @@ use crate::parser::Source; +use super::sexp::Token; + /// Check if the child string slice is a slice of the parent string slice. fn is_slice_of(parent: &str, child: &str) -> bool { let parent_start = parent.as_ptr() as usize; @@ -19,3 +21,19 @@ pub fn get_offsets<'s, S: Source<'s>>(source: &'s str, rust_object: &'s S) -> (u let end = offset + rust_object_source.len(); (offset, end) } + +pub fn assert_name<'s>(emacs: &'s Token<'s>, name: &str) -> Result<(), Box> { + let children = emacs.as_list()?; + let first_child = children + .first() + .ok_or("Should have at least one child.")? + .as_atom()?; + if first_child != name { + Err(format!( + "Expected a {expected} cell, but found a {found} cell.", + expected = name, + found = first_child + ))?; + } + Ok(()) +}