diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 17156b1..da654d6 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -1,13 +1,16 @@ +use std::borrow::Cow; // TODO: Add a check for unexpected keys in the properties use std::collections::BTreeSet; use std::collections::HashSet; +use super::elisp_fact::ElispFact; +use super::elisp_fact::GetElispFact; use super::sexp::unquote; use super::sexp::Token; -use super::util::assert_bounds; -use super::util::assert_name; +use super::util::compare_standard_properties; use super::util::get_property; use crate::types::AngleLink; +use crate::types::BabelCall; use crate::types::Bold; use crate::types::CheckboxType; use crate::types::Citation; @@ -80,7 +83,7 @@ pub enum DiffEntry<'s> { #[derive(Debug)] pub struct DiffResult<'s> { status: DiffStatus, - name: String, + name: Cow<'s, str>, message: Option, children: Vec>, rust_source: &'s str, @@ -96,7 +99,7 @@ enum DiffStatus { #[derive(Debug)] pub struct DiffLayer<'s> { - name: String, + name: Cow<'s, str>, children: Vec>, } @@ -280,10 +283,14 @@ impl<'s> DiffLayer<'s> { } fn artificial_diff_scope<'s>( - name: String, + name: &'static str, children: Vec>, ) -> Result, Box> { - Ok(DiffLayer { name, children }.into()) + Ok(DiffLayer { + name: name.into(), + children, + } + .into()) } fn compare_element<'s>( @@ -319,7 +326,7 @@ fn compare_element<'s>( let mut compare_result = match compare_result.unwrap_or_else(|e| { DiffResult { status: DiffStatus::Bad, - name: "error!".to_owned(), + name: "error!".into(), message: Some(e.to_string()), children: Vec::new(), rust_source: rust.get_standard_properties().get_source(), @@ -333,7 +340,7 @@ fn compare_element<'s>( } }; - match assert_bounds(source, emacs, rust.get_standard_properties()) { + match compare_standard_properties(source, emacs, rust) { Err(err) => { compare_result.status = DiffStatus::Bad; compare_result.message = Some(err.to_string()) @@ -381,7 +388,7 @@ fn compare_object<'s>( let mut compare_result = match compare_result.unwrap_or_else(|e| { DiffResult { status: DiffStatus::Bad, - name: "error!".to_owned(), + name: rust.get_elisp_fact().get_elisp_name(), message: Some(e.to_string()), children: Vec::new(), rust_source: rust.get_standard_properties().get_source(), @@ -398,7 +405,7 @@ fn compare_object<'s>( // PlainText is a special case because upstream Org-Mode uses relative values for the bounds in plaintext rather than absolute so the below checks do not account for that. if let Object::PlainText(_) = rust { } else { - match assert_bounds(source, emacs, rust.get_standard_properties()) { + match compare_standard_properties(source, emacs, rust) { Err(err) => { compare_result.status = DiffStatus::Bad; compare_result.message = Some(err.to_string()) @@ -417,9 +424,13 @@ pub fn compare_document<'s>( let children = emacs.as_list()?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; - let emacs_name = "org-data"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; + let mut message = None; + match compare_standard_properties(rust.source, emacs, rust) { + Err(err) => { + this_status = DiffStatus::Bad; + message = Some(err.to_string()) + } + Ok(_) => {} } // TODO: Compare :path :CATEGORY @@ -456,8 +467,8 @@ pub fn compare_document<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), - message: None, + name: rust.get_elisp_name(), + message, children: child_status, rust_source: rust.get_source(), emacs_token: emacs, @@ -474,25 +485,22 @@ fn compare_section<'s>( let mut this_status = DiffStatus::Good; let mut child_status = Vec::new(); let mut message = None; - let emacs_name = "section"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - match assert_bounds(source, emacs, rust) { + match compare_standard_properties(source, emacs, rust) { Err(err) => { this_status = DiffStatus::Bad; message = Some(err.to_string()) } Ok(_) => {} - }; + } + 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: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -510,18 +518,14 @@ fn compare_heading<'s>( 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; - } - match assert_bounds(source, emacs, rust) { + match compare_standard_properties(source, emacs, rust) { Err(err) => { this_status = DiffStatus::Bad; message = Some(err.to_string()) } Ok(_) => {} - }; + } // Compare level let level = get_property(emacs, ":level")? @@ -601,7 +605,7 @@ fn compare_heading<'s>( .zip(rust.title.iter()) .map(|(emacs_child, rust_child)| compare_object(source, emacs_child, rust_child)) .collect::, _>>()?; - child_status.push(artificial_diff_scope("title".to_owned(), title_status)?); + child_status.push(artificial_diff_scope("title", title_status)?); } }; @@ -673,11 +677,11 @@ fn compare_heading<'s>( } }) .collect::, _>>()?; - child_status.push(artificial_diff_scope("section".to_owned(), section_status)?); + child_status.push(artificial_diff_scope("section", section_status)?); Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -719,20 +723,8 @@ fn compare_paragraph<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "paragraph"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_object(source, emacs_child, rust_child)?); @@ -740,7 +732,7 @@ fn compare_paragraph<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -756,21 +748,8 @@ fn compare_plain_list<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "plain-list"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; - + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type // // :type is an unquoted atom of either descriptive, ordered, or unordered @@ -781,7 +760,7 @@ fn compare_plain_list<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -799,18 +778,14 @@ fn compare_plain_list_item<'s>( let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "item"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { + // This is not called from compare_element so we have to duplicate all the common checks here. + match compare_standard_properties(source, emacs, rust) { Err(err) => { this_status = DiffStatus::Bad; message = Some(err.to_string()) } Ok(_) => {} - }; + } // Compare tag let tag = get_property(emacs, ":tag")?; @@ -827,7 +802,7 @@ fn compare_plain_list_item<'s>( .zip(rust.tag.iter()) .map(|(emacs_child, rust_child)| compare_object(source, emacs_child, rust_child)) .collect::, _>>()?; - child_status.push(artificial_diff_scope("tag".to_owned(), tag_status)?); + child_status.push(artificial_diff_scope("tag", tag_status)?); } }; @@ -838,10 +813,7 @@ fn compare_plain_list_item<'s>( .zip(rust.children.iter()) .map(|(emacs_child, rust_child)| compare_element(source, emacs_child, rust_child)) .collect::, _>>()?; - child_status.push(artificial_diff_scope( - "contents".to_owned(), - contents_status, - )?); + child_status.push(artificial_diff_scope("contents", contents_status)?); // TODO: Compare :bullet :counter :pre-blank @@ -866,7 +838,7 @@ fn compare_plain_list_item<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -882,25 +854,8 @@ fn compare_greater_block<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = match rust.name.to_lowercase().as_str() { - "center" => "center-block", - "quote" => "quote-block", - _ => "special-block", - }; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; - + let this_status = DiffStatus::Good; + let message = None; // TODO: Special block compare :type :parameters // Center and quote block has no additional properties @@ -910,7 +865,7 @@ fn compare_greater_block<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -926,20 +881,8 @@ fn compare_dynamic_block<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - if assert_name(emacs, "dynamic-block").is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; - + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :block-name :arguments for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { @@ -948,7 +891,7 @@ fn compare_dynamic_block<'s>( Ok(DiffResult { status: this_status, - name: "dynamic-block".to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -964,21 +907,8 @@ fn compare_footnote_definition<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "footnote-definition"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; - + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :label :pre-blank for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { @@ -987,7 +917,7 @@ fn compare_footnote_definition<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -997,31 +927,18 @@ fn compare_footnote_definition<'s>( } fn compare_comment<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Comment<'s>, ) -> Result, Box> { let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "comment"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; - + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1037,21 +954,8 @@ fn compare_drawer<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "drawer"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; - + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :drawer-name for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { @@ -1060,7 +964,7 @@ fn compare_drawer<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1076,20 +980,8 @@ fn compare_property_drawer<'s>( ) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "property-drawer"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { child_status.push(compare_node_property(source, emacs_child, rust_child)?); @@ -1097,7 +989,7 @@ fn compare_property_drawer<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1114,24 +1006,20 @@ fn compare_node_property<'s>( let child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "node-property"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { + // This is not called from compare_element so we must duplicate all the tests here. + match compare_standard_properties(source, emacs, rust) { Err(err) => { this_status = DiffStatus::Bad; message = Some(err.to_string()) } Ok(_) => {} - }; + } // TODO: Compare :key :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1149,18 +1037,6 @@ fn compare_table<'s>( let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "table"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; // Compare formulas // @@ -1208,7 +1084,7 @@ fn compare_table<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1226,18 +1102,14 @@ fn compare_table_row<'s>( let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "table-row"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { + // This is not called from compare_element so we must duplicate all the tests here. + match compare_standard_properties(source, emacs, rust) { Err(err) => { this_status = DiffStatus::Bad; message = Some(err.to_string()) } Ok(_) => {} - }; + } // TODO: Compare :type // @@ -1249,7 +1121,7 @@ fn compare_table_row<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1267,24 +1139,20 @@ fn compare_table_cell<'s>( let child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "table-cell"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { + // This is not called from compare_object so we must duplicate all the tests here. + match compare_standard_properties(source, emacs, rust) { Err(err) => { this_status = DiffStatus::Bad; message = Some(err.to_string()) } Ok(_) => {} - }; + } for (_emacs_child, _rust_child) in children.iter().skip(2).zip(rust.children.iter()) {} Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1294,32 +1162,20 @@ fn compare_table_cell<'s>( } fn compare_verse_block<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s VerseBlock<'s>, ) -> Result, Box> { let children = emacs.as_list()?; let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "verse-block"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; for (_emacs_child, _rust_child) in children.iter().skip(2).zip(rust.children.iter()) {} Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1329,30 +1185,18 @@ fn compare_verse_block<'s>( } fn compare_comment_block<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s CommentBlock<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "comment-block"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1362,30 +1206,18 @@ fn compare_comment_block<'s>( } fn compare_example_block<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s ExampleBlock<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "example-block"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value :switches :number-lines :preserve-indent :retain-labels :use-labels :label-fmt Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1395,30 +1227,18 @@ fn compare_example_block<'s>( } fn compare_export_block<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s ExportBlock<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "export-block"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1428,30 +1248,18 @@ fn compare_export_block<'s>( } fn compare_src_block<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s SrcBlock<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "src-block"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :language :switches :parameters :number-lines :preserve-indent :retain-labels :use-labels :label-fmt :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1461,30 +1269,18 @@ fn compare_src_block<'s>( } fn compare_clock<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Clock<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "clock"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :status :value :duration Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1494,30 +1290,18 @@ fn compare_clock<'s>( } fn compare_diary_sexp<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s DiarySexp<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "diary-sexp"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1527,30 +1311,18 @@ fn compare_diary_sexp<'s>( } fn compare_planning<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Planning<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "planning"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :closed :deadline :scheduled Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1560,31 +1332,19 @@ fn compare_planning<'s>( } fn compare_fixed_width_area<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s FixedWidthArea<'s>, ) -> Result, Box> { let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "fixed-width"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1594,29 +1354,17 @@ fn compare_fixed_width_area<'s>( } fn compare_horizontal_rule<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s HorizontalRule<'s>, ) -> Result, Box> { let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "horizontal-rule"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1626,25 +1374,13 @@ fn compare_horizontal_rule<'s>( } fn compare_keyword<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Keyword<'s>, ) -> Result, Box> { let child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "keyword"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; let key = unquote( get_property(emacs, ":key")? @@ -1673,7 +1409,7 @@ fn compare_keyword<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1683,25 +1419,13 @@ fn compare_keyword<'s>( } fn compare_babel_call<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, - rust: &'s Keyword<'s>, + rust: &'s BabelCall<'s>, ) -> Result, Box> { let child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - let emacs_name = "babel-call"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; // TODO: Compare :call :inside-header :arguments :end-header let value = unquote( @@ -1719,7 +1443,7 @@ fn compare_babel_call<'s>( Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1729,31 +1453,19 @@ fn compare_babel_call<'s>( } fn compare_latex_environment<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s LatexEnvironment<'s>, ) -> Result, Box> { let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "latex-environment"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: child_status, rust_source: rust.get_source(), @@ -1803,7 +1515,7 @@ fn compare_plain_text<'s>( Ok(DiffResult { status: this_status, - name: "plain-text".to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source, @@ -1813,28 +1525,16 @@ fn compare_plain_text<'s>( } fn compare_bold<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Bold<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "bold"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1844,28 +1544,16 @@ fn compare_bold<'s>( } fn compare_italic<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Italic<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "italic"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1875,28 +1563,16 @@ fn compare_italic<'s>( } fn compare_underline<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Underline<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "underline"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1906,30 +1582,18 @@ fn compare_underline<'s>( } fn compare_verbatim<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Verbatim<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "verbatim"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1939,30 +1603,18 @@ fn compare_verbatim<'s>( } fn compare_code<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Code<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "code"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -1972,28 +1624,16 @@ fn compare_code<'s>( } fn compare_strike_through<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s StrikeThrough<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "strike-through"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2003,30 +1643,18 @@ fn compare_strike_through<'s>( } fn compare_regular_link<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s RegularLink<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "link"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type :path :format :raw-link :application :search-option Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2036,30 +1664,18 @@ fn compare_regular_link<'s>( } fn compare_radio_link<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s RadioLink<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "link"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type :path :format :raw-link :application :search-option Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2069,30 +1685,18 @@ fn compare_radio_link<'s>( } fn compare_radio_target<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s RadioTarget<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "radio-target"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2102,30 +1706,18 @@ fn compare_radio_target<'s>( } fn compare_plain_link<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s PlainLink<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "link"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type :path :format :raw-link :application :search-option Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2135,30 +1727,18 @@ fn compare_plain_link<'s>( } fn compare_angle_link<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s AngleLink<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "link"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type :path :format :raw-link :application :search-option Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2168,30 +1748,18 @@ fn compare_angle_link<'s>( } fn compare_org_macro<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s OrgMacro<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "macro"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :key :value :args Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2201,30 +1769,18 @@ fn compare_org_macro<'s>( } fn compare_entity<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Entity<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "entity"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :name :latex :latex-math-p :html :ascii :latin1 :utf-8 :use-brackets-p Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2234,30 +1790,18 @@ fn compare_entity<'s>( } fn compare_latex_fragment<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s LatexFragment<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "latex-fragment"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2267,30 +1811,18 @@ fn compare_latex_fragment<'s>( } fn compare_export_snippet<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s ExportSnippet<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "export-snippet"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :back-end :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2300,30 +1832,18 @@ fn compare_export_snippet<'s>( } fn compare_footnote_reference<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s FootnoteReference<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "footnote-reference"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :label :type Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2333,30 +1853,18 @@ fn compare_footnote_reference<'s>( } fn compare_citation<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Citation<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "citation"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :style :prefix :suffix Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2366,30 +1874,18 @@ fn compare_citation<'s>( } fn compare_citation_reference<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s CitationReference<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "citation-reference"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :key :prefix :suffix Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2399,30 +1895,18 @@ fn compare_citation_reference<'s>( } fn compare_inline_babel_call<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s InlineBabelCall<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "inline-babel-call"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :call :inside-header :arguments :end-header :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2432,30 +1916,18 @@ fn compare_inline_babel_call<'s>( } fn compare_inline_source_block<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s InlineSourceBlock<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "inline-src-block"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :language :value :parameters Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2465,28 +1937,16 @@ fn compare_inline_source_block<'s>( } fn compare_line_break<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s LineBreak<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "line-break"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2496,30 +1956,18 @@ fn compare_line_break<'s>( } fn compare_target<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Target<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "target"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2529,30 +1977,18 @@ fn compare_target<'s>( } fn compare_statistics_cookie<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s StatisticsCookie<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "statistics-cookie"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :value Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2562,30 +1998,18 @@ fn compare_statistics_cookie<'s>( } fn compare_subscript<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Subscript<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "subscript"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :use-brackets-p Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2595,30 +2019,18 @@ fn compare_subscript<'s>( } fn compare_superscript<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Superscript<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "superscript"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :use-brackets-p Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), @@ -2628,30 +2040,18 @@ fn compare_superscript<'s>( } fn compare_timestamp<'s>( - source: &'s str, + _source: &'s str, emacs: &'s Token<'s>, rust: &'s Timestamp<'s>, ) -> Result, Box> { - let mut this_status = DiffStatus::Good; - let mut message = None; - let emacs_name = "timestamp"; - if assert_name(emacs, emacs_name).is_err() { - this_status = DiffStatus::Bad; - } - - match assert_bounds(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - }; + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type :range-type :raw-value :year-start :month-start :day-start :hour-start :minute-start :year-end :month-end :day-end :hour-end :minute-end Ok(DiffResult { status: this_status, - name: emacs_name.to_owned(), + name: rust.get_elisp_name(), message, children: Vec::new(), rust_source: rust.get_source(), diff --git a/src/compare/elisp_fact.rs b/src/compare/elisp_fact.rs new file mode 100644 index 0000000..4646f7e --- /dev/null +++ b/src/compare/elisp_fact.rs @@ -0,0 +1,474 @@ +use std::borrow::Cow; + +use crate::types::AngleLink; +use crate::types::BabelCall; +use crate::types::Bold; +use crate::types::Citation; +use crate::types::CitationReference; +use crate::types::Clock; +use crate::types::Code; +use crate::types::Comment; +use crate::types::CommentBlock; +use crate::types::DiarySexp; +use crate::types::Document; +use crate::types::Drawer; +use crate::types::DynamicBlock; +use crate::types::Element; +use crate::types::Entity; +use crate::types::ExampleBlock; +use crate::types::ExportBlock; +use crate::types::ExportSnippet; +use crate::types::FixedWidthArea; +use crate::types::FootnoteDefinition; +use crate::types::FootnoteReference; +use crate::types::GreaterBlock; +use crate::types::Heading; +use crate::types::HorizontalRule; +use crate::types::InlineBabelCall; +use crate::types::InlineSourceBlock; +use crate::types::Italic; +use crate::types::Keyword; +use crate::types::LatexEnvironment; +use crate::types::LatexFragment; +use crate::types::LineBreak; +use crate::types::NodeProperty; +use crate::types::Object; +use crate::types::OrgMacro; +use crate::types::Paragraph; +use crate::types::PlainLink; +use crate::types::PlainList; +use crate::types::PlainListItem; +use crate::types::PlainText; +use crate::types::Planning; +use crate::types::PropertyDrawer; +use crate::types::RadioLink; +use crate::types::RadioTarget; +use crate::types::RegularLink; +use crate::types::Section; +use crate::types::SrcBlock; +use crate::types::StatisticsCookie; +use crate::types::StrikeThrough; +use crate::types::Subscript; +use crate::types::Superscript; +use crate::types::Table; +use crate::types::TableCell; +use crate::types::TableRow; +use crate::types::Target; +use crate::types::Timestamp; +use crate::types::Underline; +use crate::types::Verbatim; +use crate::types::VerseBlock; + +pub(crate) trait ElispFact<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str>; +} + +pub(crate) trait GetElispFact<'s> { + fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s>; +} + +impl<'s, I: ElispFact<'s>> GetElispFact<'s> for I { + fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s> { + self + } +} + +impl<'s> GetElispFact<'s> for Element<'s> { + fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s> { + match self { + Element::Paragraph(inner) => inner, + Element::PlainList(inner) => inner, + Element::GreaterBlock(inner) => inner, + Element::DynamicBlock(inner) => inner, + Element::FootnoteDefinition(inner) => inner, + Element::Comment(inner) => inner, + Element::Drawer(inner) => inner, + Element::PropertyDrawer(inner) => inner, + Element::Table(inner) => inner, + Element::VerseBlock(inner) => inner, + Element::CommentBlock(inner) => inner, + Element::ExampleBlock(inner) => inner, + Element::ExportBlock(inner) => inner, + Element::SrcBlock(inner) => inner, + Element::Clock(inner) => inner, + Element::DiarySexp(inner) => inner, + Element::Planning(inner) => inner, + Element::FixedWidthArea(inner) => inner, + Element::HorizontalRule(inner) => inner, + Element::Keyword(inner) => inner, + Element::BabelCall(inner) => inner, + Element::LatexEnvironment(inner) => inner, + } + } +} + +impl<'s> GetElispFact<'s> for Object<'s> { + fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s> { + match self { + Object::Bold(inner) => inner, + Object::Italic(inner) => inner, + Object::Underline(inner) => inner, + Object::StrikeThrough(inner) => inner, + Object::Code(inner) => inner, + Object::Verbatim(inner) => inner, + Object::PlainText(inner) => inner, + Object::RegularLink(inner) => inner, + Object::RadioLink(inner) => inner, + Object::RadioTarget(inner) => inner, + Object::PlainLink(inner) => inner, + Object::AngleLink(inner) => inner, + Object::OrgMacro(inner) => inner, + Object::Entity(inner) => inner, + Object::LatexFragment(inner) => inner, + Object::ExportSnippet(inner) => inner, + Object::FootnoteReference(inner) => inner, + Object::Citation(inner) => inner, + Object::CitationReference(inner) => inner, + Object::InlineBabelCall(inner) => inner, + Object::InlineSourceBlock(inner) => inner, + Object::LineBreak(inner) => inner, + Object::Target(inner) => inner, + Object::StatisticsCookie(inner) => inner, + Object::Subscript(inner) => inner, + Object::Superscript(inner) => inner, + Object::Timestamp(inner) => inner, + } + } +} + +impl<'s> ElispFact<'s> for Document<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "org-data".into() + } +} + +impl<'s> ElispFact<'s> for Section<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "section".into() + } +} + +impl<'s> ElispFact<'s> for Heading<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "headline".into() + } +} + +impl<'s> ElispFact<'s> for PlainList<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "plain-list".into() + } +} + +impl<'s> ElispFact<'s> for PlainListItem<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "item".into() + } +} + +impl<'s> ElispFact<'s> for GreaterBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + match self.name.to_lowercase().as_str() { + "center" => "center-block".into(), + "quote" => "quote-block".into(), + _ => "special-block".into(), + } + } +} + +impl<'s> ElispFact<'s> for DynamicBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "dynamic-block".into() + } +} + +impl<'s> ElispFact<'s> for FootnoteDefinition<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "footnote-definition".into() + } +} + +impl<'s> ElispFact<'s> for Drawer<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "drawer".into() + } +} + +impl<'s> ElispFact<'s> for PropertyDrawer<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "property-drawer".into() + } +} + +impl<'s> ElispFact<'s> for NodeProperty<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "node-property".into() + } +} + +impl<'s> ElispFact<'s> for Table<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "table".into() + } +} + +impl<'s> ElispFact<'s> for TableRow<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "table-row".into() + } +} + +impl<'s> ElispFact<'s> for Paragraph<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "paragraph".into() + } +} + +impl<'s> ElispFact<'s> for TableCell<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "table-cell".into() + } +} + +impl<'s> ElispFact<'s> for Comment<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "comment".into() + } +} + +impl<'s> ElispFact<'s> for VerseBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "verse-block".into() + } +} +impl<'s> ElispFact<'s> for CommentBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "comment-block".into() + } +} +impl<'s> ElispFact<'s> for ExampleBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "example-block".into() + } +} +impl<'s> ElispFact<'s> for ExportBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "export-block".into() + } +} +impl<'s> ElispFact<'s> for SrcBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "src-block".into() + } +} + +impl<'s> ElispFact<'s> for Clock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "clock".into() + } +} + +impl<'s> ElispFact<'s> for DiarySexp<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "diary-sexp".into() + } +} + +impl<'s> ElispFact<'s> for Planning<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "planning".into() + } +} + +impl<'s> ElispFact<'s> for FixedWidthArea<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "fixed-width".into() + } +} + +impl<'s> ElispFact<'s> for HorizontalRule<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "horizontal-rule".into() + } +} + +impl<'s> ElispFact<'s> for Keyword<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "keyword".into() + } +} + +impl<'s> ElispFact<'s> for BabelCall<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "babel-call".into() + } +} + +impl<'s> ElispFact<'s> for LatexEnvironment<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "latex-environment".into() + } +} + +impl<'s> ElispFact<'s> for Bold<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "bold".into() + } +} + +impl<'s> ElispFact<'s> for Italic<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "italic".into() + } +} + +impl<'s> ElispFact<'s> for Underline<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "underline".into() + } +} + +impl<'s> ElispFact<'s> for StrikeThrough<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "strike-through".into() + } +} + +impl<'s> ElispFact<'s> for Code<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "code".into() + } +} + +impl<'s> ElispFact<'s> for Verbatim<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "verbatim".into() + } +} + +impl<'s> ElispFact<'s> for RegularLink<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "link".into() + } +} + +impl<'s> ElispFact<'s> for RadioLink<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "link".into() + } +} + +impl<'s> ElispFact<'s> for RadioTarget<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "radio-target".into() + } +} + +impl<'s> ElispFact<'s> for PlainLink<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "link".into() + } +} + +impl<'s> ElispFact<'s> for AngleLink<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "link".into() + } +} + +impl<'s> ElispFact<'s> for OrgMacro<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "macro".into() + } +} + +impl<'s> ElispFact<'s> for Entity<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "entity".into() + } +} + +impl<'s> ElispFact<'s> for LatexFragment<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "latex-fragment".into() + } +} + +impl<'s> ElispFact<'s> for ExportSnippet<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "export-snippet".into() + } +} + +impl<'s> ElispFact<'s> for FootnoteReference<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "footnote-reference".into() + } +} + +impl<'s> ElispFact<'s> for Citation<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "citation".into() + } +} + +impl<'s> ElispFact<'s> for CitationReference<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "citation-reference".into() + } +} + +impl<'s> ElispFact<'s> for InlineBabelCall<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "inline-babel-call".into() + } +} + +impl<'s> ElispFact<'s> for InlineSourceBlock<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "inline-src-block".into() + } +} + +impl<'s> ElispFact<'s> for LineBreak<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "line-break".into() + } +} + +impl<'s> ElispFact<'s> for Target<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "target".into() + } +} + +impl<'s> ElispFact<'s> for StatisticsCookie<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "statistics-cookie".into() + } +} + +impl<'s> ElispFact<'s> for Subscript<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "subscript".into() + } +} + +impl<'s> ElispFact<'s> for Superscript<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "superscript".into() + } +} + +impl<'s> ElispFact<'s> for Timestamp<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + "timestamp".into() + } +} + +impl<'s> ElispFact<'s> for PlainText<'s> { + fn get_elisp_name(&'s self) -> Cow<'s, str> { + // plain text from upstream emacs does not actually have a name but this is included here to make rendering the status diff easier. + "plain-text".into() + } +} diff --git a/src/compare/mod.rs b/src/compare/mod.rs index 5fa9cc0..5c729a8 100644 --- a/src/compare/mod.rs +++ b/src/compare/mod.rs @@ -1,5 +1,6 @@ mod compare; mod diff; +mod elisp_fact; mod parse; mod sexp; mod util; diff --git a/src/compare/util.rs b/src/compare/util.rs index 3bebf2c..21580a9 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -1,4 +1,6 @@ +use super::elisp_fact::GetElispFact; use super::sexp::Token; +use crate::types::GetStandardProperties; use crate::types::StandardProperties; /// Check if the child string slice is a slice of the parent string slice. @@ -24,10 +26,24 @@ fn get_rust_byte_offsets<'s, S: StandardProperties<'s> + ?Sized>( (offset, end) } -pub(crate) fn assert_name<'s>( +pub(crate) fn compare_standard_properties< + 's, + S: GetStandardProperties<'s> + GetElispFact<'s> + ?Sized, +>( + original_document: &'s str, emacs: &'s Token<'s>, - name: &str, + rust: &'s S, ) -> Result<(), Box> { + assert_name(emacs, rust.get_elisp_fact().get_elisp_name())?; + assert_bounds(original_document, emacs, rust.get_standard_properties())?; + Ok(()) +} + +pub(crate) fn assert_name<'s, S: AsRef>( + emacs: &'s Token<'s>, + name: S, +) -> Result<(), Box> { + let name = name.as_ref(); let children = emacs.as_list()?; let first_child = children .first() @@ -35,7 +51,7 @@ pub(crate) fn assert_name<'s>( .as_atom()?; if first_child != name { Err(format!( - "Expected a {expected} cell, but found a {found} cell.", + "AST node name mismatch. Expected a (rust) {expected} cell, but found a (emacs) {found} cell.", expected = name, found = first_child ))?; diff --git a/src/parser/keyword.rs b/src/parser/keyword.rs index 8510fe9..9253590 100644 --- a/src/parser/keyword.rs +++ b/src/parser/keyword.rs @@ -24,6 +24,7 @@ use crate::error::CustomError; use crate::error::MyError; use crate::error::Res; use crate::parser::util::start_of_line; +use crate::types::BabelCall; use crate::types::Keyword; const ORG_ELEMENT_AFFILIATED_KEYWORDS: [&'static str; 13] = [ @@ -103,8 +104,16 @@ pub(crate) fn affiliated_keyword<'b, 'g, 'r, 's>( pub(crate) fn babel_call_keyword<'b, 'g, 'r, 's>( _context: RefContext<'b, 'g, 'r, 's>, input: OrgSource<'s>, -) -> Res, Keyword<'s>> { - filtered_keyword(babel_call_key)(input) +) -> Res, BabelCall<'s>> { + let (remaining, kw) = filtered_keyword(babel_call_key)(input)?; + Ok(( + remaining, + BabelCall { + source: kw.source, + key: kw.key, + value: kw.value, + }, + )) } #[cfg_attr(feature = "tracing", tracing::instrument(ret, level = "debug"))] diff --git a/src/types/element.rs b/src/types/element.rs index f0de482..a5c472c 100644 --- a/src/types/element.rs +++ b/src/types/element.rs @@ -4,6 +4,7 @@ use super::greater_element::GreaterBlock; use super::greater_element::PlainList; use super::greater_element::PropertyDrawer; use super::greater_element::Table; +use super::lesser_element::BabelCall; use super::lesser_element::Clock; use super::lesser_element::Comment; use super::lesser_element::CommentBlock; @@ -45,7 +46,7 @@ pub enum Element<'s> { FixedWidthArea(FixedWidthArea<'s>), HorizontalRule(HorizontalRule<'s>), Keyword(Keyword<'s>), - BabelCall(Keyword<'s>), + BabelCall(BabelCall<'s>), LatexEnvironment(LatexEnvironment<'s>), } diff --git a/src/types/get_standard_properties.rs b/src/types/get_standard_properties.rs index 23c3bc6..3488d30 100644 --- a/src/types/get_standard_properties.rs +++ b/src/types/get_standard_properties.rs @@ -2,9 +2,7 @@ use super::StandardProperties; pub trait GetStandardProperties<'s> { // TODO: Can I eliminate this dynamic dispatch, perhaps using nominal generic structs? Low prioritiy since this is not used during parsing. - fn get_standard_properties(&'s self) -> &'s dyn StandardProperties - where - Self: Sized; + fn get_standard_properties(&'s self) -> &'s dyn StandardProperties; } impl<'s, I: StandardProperties<'s>> GetStandardProperties<'s> for I { diff --git a/src/types/lesser_element.rs b/src/types/lesser_element.rs index 5df561e..80c3d51 100644 --- a/src/types/lesser_element.rs +++ b/src/types/lesser_element.rs @@ -91,6 +91,13 @@ pub struct Keyword<'s> { pub value: &'s str, } +#[derive(Debug)] +pub struct BabelCall<'s> { + pub source: &'s str, + pub key: &'s str, + pub value: &'s str, +} + #[derive(Debug)] pub struct LatexEnvironment<'s> { pub source: &'s str, @@ -187,6 +194,12 @@ impl<'s> StandardProperties<'s> for Keyword<'s> { } } +impl<'s> StandardProperties<'s> for BabelCall<'s> { + fn get_source(&'s self) -> &'s str { + self.source + } +} + impl<'s> StandardProperties<'s> for LatexEnvironment<'s> { fn get_source(&'s self) -> &'s str { self.source diff --git a/src/types/mod.rs b/src/types/mod.rs index 2fa408b..7fa6e80 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -27,6 +27,7 @@ pub use greater_element::PlainListItem; pub use greater_element::PropertyDrawer; pub use greater_element::Table; pub use greater_element::TableRow; +pub use lesser_element::BabelCall; pub use lesser_element::Clock; pub use lesser_element::Comment; pub use lesser_element::CommentBlock;