diff --git a/src/compare/diff.rs b/src/compare/diff.rs index 25cf74d..1075383 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -12,6 +12,7 @@ use super::util::get_property; use super::util::get_property_boolean; use super::util::get_property_quoted_string; use super::util::get_property_unquoted_atom; +use crate::types::AstNode; use crate::types::AngleLink; use crate::types::BabelCall; use crate::types::Bold; @@ -27,7 +28,6 @@ use crate::types::Document; use crate::types::DocumentElement; use crate::types::Drawer; use crate::types::DynamicBlock; -use crate::types::Element; use crate::types::Entity; use crate::types::ExampleBlock; use crate::types::ExportBlock; @@ -47,7 +47,6 @@ 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; @@ -81,20 +80,20 @@ use crate::types::Verbatim; use crate::types::VerseBlock; #[derive(Debug)] -pub enum DiffEntry<'s> { - DiffResult(DiffResult<'s>), - DiffLayer(DiffLayer<'s>), +pub enum DiffEntry<'b, 's> { + DiffResult(DiffResult<'b, 's>), + DiffLayer(DiffLayer<'b, 's>), } #[derive(Debug)] -pub struct DiffResult<'s> { +pub struct DiffResult<'b, 's> { status: DiffStatus, name: Cow<'s, str>, message: Option, - children: Vec>, + children: Vec>, rust_source: &'s str, #[allow(dead_code)] - emacs_token: &'s Token<'s>, + emacs_token: &'b Token<'s>, } #[derive(Debug, PartialEq)] @@ -104,24 +103,24 @@ enum DiffStatus { } #[derive(Debug)] -pub struct DiffLayer<'s> { +pub struct DiffLayer<'b, 's> { name: Cow<'s, str>, - children: Vec>, + children: Vec>, } -impl<'s> From> for DiffEntry<'s> { - fn from(value: DiffResult<'s>) -> Self { +impl<'b, 's> From> for DiffEntry<'b, 's> { + fn from(value: DiffResult<'b, 's>) -> Self { DiffEntry::DiffResult(value) } } -impl<'s> From> for DiffEntry<'s> { - fn from(value: DiffLayer<'s>) -> Self { +impl<'b, 's> From> for DiffEntry<'b, 's> { + fn from(value: DiffLayer<'b, 's>) -> Self { DiffEntry::DiffLayer(value) } } -impl<'s> DiffEntry<'s> { +impl<'b, 's> DiffEntry<'b, 's> { fn has_bad_children(&self) -> bool { match self { DiffEntry::DiffResult(diff) => &diff.children, @@ -158,7 +157,7 @@ impl<'s> DiffEntry<'s> { } } -impl<'s> DiffResult<'s> { +impl<'b, 's> DiffResult<'b, 's> { fn print_indented( &self, indentation: usize, @@ -250,7 +249,7 @@ impl<'s> DiffResult<'s> { } } -impl<'s> DiffLayer<'s> { +impl<'b, 's> DiffLayer<'b, 's> { fn has_bad_children(&self) -> bool { self.children .iter() @@ -288,10 +287,10 @@ impl<'s> DiffLayer<'s> { } } -fn artificial_diff_scope<'s>( +fn artificial_diff_scope<'b, 's>( name: &'static str, - children: Vec>, -) -> Result, Box> { + children: Vec>, +) -> Result, Box> { Ok(DiffLayer { name: name.into(), children, @@ -299,98 +298,70 @@ fn artificial_diff_scope<'s>( .into()) } -fn compare_element<'s>( +fn compare_ast_node<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Element<'s>, -) -> Result, Box> { - let compare_result = match rust { - Element::Paragraph(obj) => compare_paragraph(source, emacs, obj), - Element::PlainList(obj) => compare_plain_list(source, emacs, obj), - Element::GreaterBlock(obj) => compare_greater_block(source, emacs, obj), - Element::DynamicBlock(obj) => compare_dynamic_block(source, emacs, obj), - Element::FootnoteDefinition(obj) => compare_footnote_definition(source, emacs, obj), - Element::Comment(obj) => compare_comment(source, emacs, obj), - Element::Drawer(obj) => compare_drawer(source, emacs, obj), - Element::PropertyDrawer(obj) => compare_property_drawer(source, emacs, obj), - Element::Table(obj) => compare_table(source, emacs, obj), - Element::VerseBlock(obj) => compare_verse_block(source, emacs, obj), - Element::CommentBlock(obj) => compare_comment_block(source, emacs, obj), - Element::ExampleBlock(obj) => compare_example_block(source, emacs, obj), - Element::ExportBlock(obj) => compare_export_block(source, emacs, obj), - Element::SrcBlock(obj) => compare_src_block(source, emacs, obj), - Element::Clock(obj) => compare_clock(source, emacs, obj), - Element::DiarySexp(obj) => compare_diary_sexp(source, emacs, obj), - Element::Planning(obj) => compare_planning(source, emacs, obj), - Element::FixedWidthArea(obj) => compare_fixed_width_area(source, emacs, obj), - Element::HorizontalRule(obj) => compare_horizontal_rule(source, emacs, obj), - Element::Keyword(obj) => compare_keyword(source, emacs, obj), - Element::BabelCall(obj) => compare_babel_call(source, emacs, obj), - Element::LatexEnvironment(obj) => compare_latex_environment(source, emacs, obj), + emacs: &'b Token<'s>, + rust: AstNode<'b, 's>, +) -> Result, Box> { + let compare_result: Result, Box> = match rust { + AstNode::Document(node) => _compare_document(source, emacs, node), + AstNode::Heading(node) => compare_heading(source, emacs, node), + AstNode::Section(node) => compare_section(source, emacs, node), + AstNode::Paragraph(node) => compare_paragraph(source, emacs, node), + AstNode::PlainList(node) => compare_plain_list(source, emacs, node), + AstNode::PlainListItem(node) => compare_plain_list_item(source, emacs, node), + AstNode::GreaterBlock(node) => compare_greater_block(source, emacs, node), + AstNode::DynamicBlock(node) => compare_dynamic_block(source, emacs, node), + AstNode::FootnoteDefinition(node) => compare_footnote_definition(source, emacs, node), + AstNode::Comment(node) => compare_comment(source, emacs, node), + AstNode::Drawer(node) => compare_drawer(source, emacs, node), + AstNode::PropertyDrawer(node) => compare_property_drawer(source, emacs, node), + AstNode::NodeProperty(node) => compare_node_property(source, emacs, node), + AstNode::Table(node) => compare_table(source, emacs, node), + AstNode::TableRow(node) => compare_table_row(source, emacs, node), + AstNode::VerseBlock(node) => compare_verse_block(source, emacs, node), + AstNode::CommentBlock(node) => compare_comment_block(source, emacs, node), + AstNode::ExampleBlock(node) => compare_example_block(source, emacs, node), + AstNode::ExportBlock(node) => compare_export_block(source, emacs, node), + AstNode::SrcBlock(node) => compare_src_block(source, emacs, node), + AstNode::Clock(node) => compare_clock(source, emacs, node), + AstNode::DiarySexp(node) => compare_diary_sexp(source, emacs, node), + AstNode::Planning(node) => compare_planning(source, emacs, node), + AstNode::FixedWidthArea(node) => compare_fixed_width_area(source, emacs, node), + AstNode::HorizontalRule(node) => compare_horizontal_rule(source, emacs, node), + AstNode::Keyword(node) => compare_keyword(source, emacs, node), + AstNode::BabelCall(node) => compare_babel_call(source, emacs, node), + AstNode::LatexEnvironment(node) => compare_latex_environment(source, emacs, node), + AstNode::Bold(node) => compare_bold(source, emacs, node), + AstNode::Italic(node) => compare_italic(source, emacs, node), + AstNode::Underline(node) => compare_underline(source, emacs, node), + AstNode::StrikeThrough(node) => compare_strike_through(source, emacs, node), + AstNode::Code(node) => compare_code(source, emacs, node), + AstNode::Verbatim(node) => compare_verbatim(source, emacs, node), + AstNode::PlainText(node) => compare_plain_text(source, emacs, node), + AstNode::RegularLink(node) => compare_regular_link(source, emacs, node), + AstNode::RadioLink(node) => compare_radio_link(source, emacs, node), + AstNode::RadioTarget(node) => compare_radio_target(source, emacs, node), + AstNode::PlainLink(node) => compare_plain_link(source, emacs, node), + AstNode::AngleLink(node) => compare_angle_link(source, emacs, node), + AstNode::OrgMacro(node) => compare_org_macro(source, emacs, node), + AstNode::Entity(node) => compare_entity(source, emacs, node), + AstNode::LatexFragment(node) => compare_latex_fragment(source, emacs, node), + AstNode::ExportSnippet(node) => compare_export_snippet(source, emacs, node), + AstNode::FootnoteReference(node) => compare_footnote_reference(source, emacs, node), + AstNode::Citation(node) => compare_citation(source, emacs, node), + AstNode::CitationReference(node) => compare_citation_reference(source, emacs, node), + AstNode::InlineBabelCall(node) => compare_inline_babel_call(source, emacs, node), + AstNode::InlineSourceBlock(node) => compare_inline_source_block(source, emacs, node), + AstNode::LineBreak(node) => compare_line_break(source, emacs, node), + AstNode::Target(node) => compare_target(source, emacs, node), + AstNode::StatisticsCookie(node) => compare_statistics_cookie(source, emacs, node), + AstNode::Subscript(node) => compare_subscript(source, emacs, node), + AstNode::Superscript(node) => compare_superscript(source, emacs, node), + AstNode::TableCell(node) => compare_table_cell(source, emacs, node), + AstNode::Timestamp(node) => compare_timestamp(source, emacs, node), }; - let mut compare_result = match compare_result.unwrap_or_else(|e| { - DiffResult { - status: DiffStatus::Bad, - name: "error!".into(), - message: Some(e.to_string()), - children: Vec::new(), - rust_source: rust.get_standard_properties().get_source(), - emacs_token: emacs, - } - .into() - }) { - DiffEntry::DiffResult(inner) => inner, - DiffEntry::DiffLayer(_) => { - unreachable!("Layers are only interior to DiffResults of AST nodes.") - } - }; - - match compare_standard_properties(source, emacs, rust) { - Err(err) => { - compare_result.status = DiffStatus::Bad; - compare_result.message = Some(err.to_string()) - } - Ok(_) => {} - } - - Ok(compare_result.into()) -} - -fn compare_object<'s>( - source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Object<'s>, -) -> Result, Box> { - let compare_result = match rust { - Object::Bold(obj) => compare_bold(source, emacs, obj), - Object::Italic(obj) => compare_italic(source, emacs, obj), - Object::Underline(obj) => compare_underline(source, emacs, obj), - Object::Verbatim(obj) => compare_verbatim(source, emacs, obj), - Object::Code(obj) => compare_code(source, emacs, obj), - Object::StrikeThrough(obj) => compare_strike_through(source, emacs, obj), - Object::PlainText(obj) => compare_plain_text(source, emacs, obj), - Object::RegularLink(obj) => compare_regular_link(source, emacs, obj), - Object::RadioLink(obj) => compare_radio_link(source, emacs, obj), - Object::RadioTarget(obj) => compare_radio_target(source, emacs, obj), - Object::PlainLink(obj) => compare_plain_link(source, emacs, obj), - Object::AngleLink(obj) => compare_angle_link(source, emacs, obj), - Object::OrgMacro(obj) => compare_org_macro(source, emacs, obj), - Object::Entity(obj) => compare_entity(source, emacs, obj), - Object::LatexFragment(obj) => compare_latex_fragment(source, emacs, obj), - Object::ExportSnippet(obj) => compare_export_snippet(source, emacs, obj), - Object::FootnoteReference(obj) => compare_footnote_reference(source, emacs, obj), - Object::Citation(obj) => compare_citation(source, emacs, obj), - Object::CitationReference(obj) => compare_citation_reference(source, emacs, obj), - Object::InlineBabelCall(obj) => compare_inline_babel_call(source, emacs, obj), - Object::InlineSourceBlock(obj) => compare_inline_source_block(source, emacs, obj), - Object::LineBreak(obj) => compare_line_break(source, emacs, obj), - Object::Target(obj) => compare_target(source, emacs, obj), - Object::StatisticsCookie(obj) => compare_statistics_cookie(source, emacs, obj), - Object::Subscript(obj) => compare_subscript(source, emacs, obj), - Object::Superscript(obj) => compare_superscript(source, emacs, obj), - Object::Timestamp(obj) => compare_timestamp(source, emacs, obj), - }; let mut compare_result = match compare_result.unwrap_or_else(|e| { DiffResult { status: DiffStatus::Bad, @@ -409,9 +380,9 @@ 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 { + if let AstNode::PlainText(_) = rust { } else { - match compare_standard_properties(source, emacs, rust) { + match compare_standard_properties(source, emacs, &rust) { Err(err) => { compare_result.status = DiffStatus::Bad; compare_result.message = Some(err.to_string()) @@ -423,21 +394,22 @@ fn compare_object<'s>( Ok(compare_result.into()) } -pub fn compare_document<'s>( - emacs: &'s Token<'s>, - rust: &'s Document<'s>, -) -> Result, Box> { +pub fn compare_document<'b, 's>( + emacs: &'b Token<'s>, + rust: &'b Document<'s>, +) -> Result, Box> { + compare_ast_node(rust.source, emacs, rust.into()) +} + +fn _compare_document<'b, 's>( + _source: &'s str, + emacs: &'b Token<'s>, + rust: &'b Document<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - match compare_standard_properties(rust.source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - } // Compare :path // :path is a quoted string to the absolute path of the document. @@ -498,12 +470,13 @@ pub fn compare_document<'s>( if i != 0 { return Err("Section cannot be after the first child of document.".into()); } - child_status.push(compare_section( + child_status.push(compare_ast_node( rust.source, token, rust.zeroth_section .as_ref() - .ok_or("No corresponding zeroth-section")?, + .ok_or("No corresponding zeroth-section")? + .into(), )?); } else if first_cell == "headline" { let corresponding_heading = rust @@ -511,7 +484,11 @@ pub fn compare_document<'s>( .iter() .nth(i - rust.zeroth_section.as_ref().map(|_| 1).unwrap_or(0)) .ok_or("Should have a corresponding heading.")?; - child_status.push(compare_heading(rust.source, token, corresponding_heading)?); + child_status.push(compare_ast_node( + rust.source, + token, + corresponding_heading.into(), + )?); } else { return Err(format!( "Document should only contain sections and headlines, found: {}", @@ -532,26 +509,18 @@ pub fn compare_document<'s>( .into()) } -fn compare_section<'s>( +fn compare_section<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Section<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Section<'s>, +) -> Result, Box> { let children = emacs.as_list()?; - let mut this_status = DiffStatus::Good; + let this_status = DiffStatus::Good; let mut child_status = Vec::new(); - let mut message = None; - - match compare_standard_properties(source, emacs, rust) { - Err(err) => { - this_status = DiffStatus::Bad; - message = Some(err.to_string()) - } - Ok(_) => {} - } + let message = None; for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_element(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -565,24 +534,16 @@ fn compare_section<'s>( .into()) } -fn compare_heading<'s>( +fn compare_heading<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Heading<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Heading<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - 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")? .ok_or("Level should not be nil")? @@ -659,7 +620,9 @@ fn compare_heading<'s>( .as_list()? .iter() .zip(rust.title.iter()) - .map(|(emacs_child, rust_child)| compare_object(source, emacs_child, rust_child)) + .map(|(emacs_child, rust_child)| { + compare_ast_node(source, emacs_child, rust_child.into()) + }) .collect::, _>>()?; child_status.push(artificial_diff_scope("title", title_status)?); } @@ -748,10 +711,10 @@ fn compare_heading<'s>( .zip(rust.children.iter()) .map(|(emacs_child, rust_child)| match rust_child { DocumentElement::Heading(rust_heading) => { - compare_heading(source, emacs_child, rust_heading) + compare_ast_node(source, emacs_child, rust_heading.into()) } DocumentElement::Section(rust_section) => { - compare_section(source, emacs_child, rust_section) + compare_ast_node(source, emacs_child, rust_section.into()) } }) .collect::, _>>()?; @@ -768,8 +731,8 @@ fn compare_heading<'s>( .into()) } -fn get_tags_from_heading<'s>( - emacs: &'s Token<'s>, +fn get_tags_from_heading<'b, 's>( + emacs: &'b Token<'s>, ) -> Result, Box> { let tags = match get_property(emacs, ":tags")? { Some(prop) => prop, @@ -794,18 +757,18 @@ fn get_tags_from_heading<'s>( Ok(tags) } -fn compare_paragraph<'s>( +fn compare_paragraph<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Paragraph<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Paragraph<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); 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)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -819,11 +782,11 @@ fn compare_paragraph<'s>( .into()) } -fn compare_plain_list<'s>( +fn compare_plain_list<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s PlainList<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b PlainList<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -847,7 +810,7 @@ fn compare_plain_list<'s>( } for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_plain_list_item(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -861,23 +824,15 @@ fn compare_plain_list<'s>( .into()) } -fn compare_plain_list_item<'s>( +fn compare_plain_list_item<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s PlainListItem<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b PlainListItem<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; - // 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")?; @@ -892,7 +847,9 @@ fn compare_plain_list_item<'s>( .as_list()? .iter() .zip(rust.tag.iter()) - .map(|(emacs_child, rust_child)| compare_object(source, emacs_child, rust_child)) + .map(|(emacs_child, rust_child)| { + compare_ast_node(source, emacs_child, rust_child.into()) + }) .collect::, _>>()?; child_status.push(artificial_diff_scope("tag", tag_status)?); } @@ -903,7 +860,7 @@ fn compare_plain_list_item<'s>( .iter() .skip(2) .zip(rust.children.iter()) - .map(|(emacs_child, rust_child)| compare_element(source, emacs_child, rust_child)) + .map(|(emacs_child, rust_child)| compare_ast_node(source, emacs_child, rust_child.into())) .collect::, _>>()?; child_status.push(artificial_diff_scope("contents", contents_status)?); @@ -986,11 +943,11 @@ fn compare_plain_list_item<'s>( .into()) } -fn compare_greater_block<'s>( +fn compare_greater_block<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s GreaterBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b GreaterBlock<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let this_status = DiffStatus::Good; @@ -999,7 +956,7 @@ fn compare_greater_block<'s>( // Center and quote block has no additional properties for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_element(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1013,11 +970,11 @@ fn compare_greater_block<'s>( .into()) } -fn compare_dynamic_block<'s>( +fn compare_dynamic_block<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s DynamicBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b DynamicBlock<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let this_status = DiffStatus::Good; @@ -1025,7 +982,7 @@ fn compare_dynamic_block<'s>( // TODO: Compare :block-name :arguments for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_element(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1039,11 +996,11 @@ fn compare_dynamic_block<'s>( .into()) } -fn compare_footnote_definition<'s>( +fn compare_footnote_definition<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s FootnoteDefinition<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b FootnoteDefinition<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let this_status = DiffStatus::Good; @@ -1051,7 +1008,7 @@ fn compare_footnote_definition<'s>( // TODO: Compare :label :pre-blank for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_element(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1065,11 +1022,11 @@ fn compare_footnote_definition<'s>( .into()) } -fn compare_comment<'s>( +fn compare_comment<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Comment<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Comment<'s>, +) -> Result, Box> { let child_status = Vec::new(); let this_status = DiffStatus::Good; let message = None; @@ -1086,11 +1043,11 @@ fn compare_comment<'s>( .into()) } -fn compare_drawer<'s>( +fn compare_drawer<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Drawer<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Drawer<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let this_status = DiffStatus::Good; @@ -1098,7 +1055,7 @@ fn compare_drawer<'s>( // TODO: Compare :drawer-name for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_element(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1112,18 +1069,18 @@ fn compare_drawer<'s>( .into()) } -fn compare_property_drawer<'s>( +fn compare_property_drawer<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s PropertyDrawer<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b PropertyDrawer<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); 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)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1137,22 +1094,14 @@ fn compare_property_drawer<'s>( .into()) } -fn compare_node_property<'s>( - source: &'s str, - emacs: &'s Token<'s>, - rust: &'s NodeProperty<'s>, -) -> Result, Box> { +fn compare_node_property<'b, 's>( + _source: &'s str, + emacs: &'b Token<'s>, + rust: &'b NodeProperty<'s>, +) -> Result, Box> { let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - // 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(_) => {} - } + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :key :value @@ -1167,11 +1116,11 @@ fn compare_node_property<'s>( .into()) } -fn compare_table<'s>( +fn compare_table<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Table<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Table<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); let mut this_status = DiffStatus::Good; @@ -1218,7 +1167,7 @@ fn compare_table<'s>( // TODO: Compare :type :value for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_table_row(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1232,30 +1181,22 @@ fn compare_table<'s>( .into()) } -fn compare_table_row<'s>( +fn compare_table_row<'b, 's>( source: &'s str, - emacs: &'s Token<'s>, - rust: &'s TableRow<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b TableRow<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let mut child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - // 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(_) => {} - } + let this_status = DiffStatus::Good; + let message = None; // TODO: Compare :type // // :type is an unquoted atom of either standard or rule for (emacs_child, rust_child) in children.iter().skip(2).zip(rust.children.iter()) { - child_status.push(compare_table_cell(source, emacs_child, rust_child)?); + child_status.push(compare_ast_node(source, emacs_child, rust_child.into())?); } Ok(DiffResult { @@ -1269,42 +1210,11 @@ fn compare_table_row<'s>( .into()) } -fn compare_table_cell<'s>( - source: &'s str, - emacs: &'s Token<'s>, - rust: &'s TableCell<'s>, -) -> Result, Box> { - let children = emacs.as_list()?; - let child_status = Vec::new(); - let mut this_status = DiffStatus::Good; - let mut message = None; - // 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: rust.get_elisp_name(), - message, - children: child_status, - rust_source: rust.get_source(), - emacs_token: emacs, - } - .into()) -} - -fn compare_verse_block<'s>( +fn compare_table_cell<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s VerseBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b TableCell<'s>, +) -> Result, Box> { let children = emacs.as_list()?; let child_status = Vec::new(); let this_status = DiffStatus::Good; @@ -1323,11 +1233,34 @@ fn compare_verse_block<'s>( .into()) } -fn compare_comment_block<'s>( +fn compare_verse_block<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s CommentBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b VerseBlock<'s>, +) -> Result, Box> { + let children = emacs.as_list()?; + let child_status = Vec::new(); + 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: rust.get_elisp_name(), + message, + children: child_status, + rust_source: rust.get_source(), + emacs_token: emacs, + } + .into()) +} + +fn compare_comment_block<'b, 's>( + _source: &'s str, + emacs: &'b Token<'s>, + rust: &'b CommentBlock<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1344,11 +1277,11 @@ fn compare_comment_block<'s>( .into()) } -fn compare_example_block<'s>( +fn compare_example_block<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s ExampleBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b ExampleBlock<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1365,11 +1298,11 @@ fn compare_example_block<'s>( .into()) } -fn compare_export_block<'s>( +fn compare_export_block<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s ExportBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b ExportBlock<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1386,11 +1319,11 @@ fn compare_export_block<'s>( .into()) } -fn compare_src_block<'s>( +fn compare_src_block<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s SrcBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b SrcBlock<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1407,11 +1340,11 @@ fn compare_src_block<'s>( .into()) } -fn compare_clock<'s>( +fn compare_clock<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Clock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Clock<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1428,11 +1361,11 @@ fn compare_clock<'s>( .into()) } -fn compare_diary_sexp<'s>( +fn compare_diary_sexp<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s DiarySexp<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b DiarySexp<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1449,11 +1382,11 @@ fn compare_diary_sexp<'s>( .into()) } -fn compare_planning<'s>( +fn compare_planning<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Planning<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Planning<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1470,11 +1403,11 @@ fn compare_planning<'s>( .into()) } -fn compare_fixed_width_area<'s>( +fn compare_fixed_width_area<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s FixedWidthArea<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b FixedWidthArea<'s>, +) -> Result, Box> { let child_status = Vec::new(); let this_status = DiffStatus::Good; let message = None; @@ -1492,11 +1425,11 @@ fn compare_fixed_width_area<'s>( .into()) } -fn compare_horizontal_rule<'s>( +fn compare_horizontal_rule<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s HorizontalRule<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b HorizontalRule<'s>, +) -> Result, Box> { let child_status = Vec::new(); let this_status = DiffStatus::Good; let message = None; @@ -1512,11 +1445,11 @@ fn compare_horizontal_rule<'s>( .into()) } -fn compare_keyword<'s>( +fn compare_keyword<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Keyword<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Keyword<'s>, +) -> Result, Box> { let child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; @@ -1557,11 +1490,11 @@ fn compare_keyword<'s>( .into()) } -fn compare_babel_call<'s>( +fn compare_babel_call<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s BabelCall<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b BabelCall<'s>, +) -> Result, Box> { let child_status = Vec::new(); let mut this_status = DiffStatus::Good; let mut message = None; @@ -1591,11 +1524,11 @@ fn compare_babel_call<'s>( .into()) } -fn compare_latex_environment<'s>( +fn compare_latex_environment<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s LatexEnvironment<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b LatexEnvironment<'s>, +) -> Result, Box> { let child_status = Vec::new(); let this_status = DiffStatus::Good; let message = None; @@ -1613,11 +1546,11 @@ fn compare_latex_environment<'s>( .into()) } -fn compare_plain_text<'s>( +fn compare_plain_text<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s PlainText<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b PlainText<'s>, +) -> Result, Box> { let mut this_status = DiffStatus::Good; let mut message = None; let rust_source = rust.get_source(); @@ -1663,11 +1596,11 @@ fn compare_plain_text<'s>( .into()) } -fn compare_bold<'s>( +fn compare_bold<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Bold<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Bold<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1682,11 +1615,11 @@ fn compare_bold<'s>( .into()) } -fn compare_italic<'s>( +fn compare_italic<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Italic<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Italic<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1701,11 +1634,11 @@ fn compare_italic<'s>( .into()) } -fn compare_underline<'s>( +fn compare_underline<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Underline<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Underline<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1720,11 +1653,11 @@ fn compare_underline<'s>( .into()) } -fn compare_verbatim<'s>( +fn compare_verbatim<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Verbatim<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Verbatim<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1741,11 +1674,11 @@ fn compare_verbatim<'s>( .into()) } -fn compare_code<'s>( +fn compare_code<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Code<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Code<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1762,11 +1695,11 @@ fn compare_code<'s>( .into()) } -fn compare_strike_through<'s>( +fn compare_strike_through<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s StrikeThrough<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b StrikeThrough<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1781,11 +1714,11 @@ fn compare_strike_through<'s>( .into()) } -fn compare_regular_link<'s>( +fn compare_regular_link<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s RegularLink<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b RegularLink<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1802,11 +1735,11 @@ fn compare_regular_link<'s>( .into()) } -fn compare_radio_link<'s>( +fn compare_radio_link<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s RadioLink<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b RadioLink<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1823,11 +1756,11 @@ fn compare_radio_link<'s>( .into()) } -fn compare_radio_target<'s>( +fn compare_radio_target<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s RadioTarget<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b RadioTarget<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1844,11 +1777,11 @@ fn compare_radio_target<'s>( .into()) } -fn compare_plain_link<'s>( +fn compare_plain_link<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s PlainLink<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b PlainLink<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1865,11 +1798,11 @@ fn compare_plain_link<'s>( .into()) } -fn compare_angle_link<'s>( +fn compare_angle_link<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s AngleLink<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b AngleLink<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1886,11 +1819,11 @@ fn compare_angle_link<'s>( .into()) } -fn compare_org_macro<'s>( +fn compare_org_macro<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s OrgMacro<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b OrgMacro<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1907,11 +1840,11 @@ fn compare_org_macro<'s>( .into()) } -fn compare_entity<'s>( +fn compare_entity<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Entity<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Entity<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1928,11 +1861,11 @@ fn compare_entity<'s>( .into()) } -fn compare_latex_fragment<'s>( +fn compare_latex_fragment<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s LatexFragment<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b LatexFragment<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1949,11 +1882,11 @@ fn compare_latex_fragment<'s>( .into()) } -fn compare_export_snippet<'s>( +fn compare_export_snippet<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s ExportSnippet<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b ExportSnippet<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1970,11 +1903,11 @@ fn compare_export_snippet<'s>( .into()) } -fn compare_footnote_reference<'s>( +fn compare_footnote_reference<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s FootnoteReference<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b FootnoteReference<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -1991,11 +1924,11 @@ fn compare_footnote_reference<'s>( .into()) } -fn compare_citation<'s>( +fn compare_citation<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Citation<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Citation<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2012,11 +1945,11 @@ fn compare_citation<'s>( .into()) } -fn compare_citation_reference<'s>( +fn compare_citation_reference<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s CitationReference<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b CitationReference<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2033,11 +1966,11 @@ fn compare_citation_reference<'s>( .into()) } -fn compare_inline_babel_call<'s>( +fn compare_inline_babel_call<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s InlineBabelCall<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b InlineBabelCall<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2054,11 +1987,11 @@ fn compare_inline_babel_call<'s>( .into()) } -fn compare_inline_source_block<'s>( +fn compare_inline_source_block<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s InlineSourceBlock<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b InlineSourceBlock<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2075,11 +2008,11 @@ fn compare_inline_source_block<'s>( .into()) } -fn compare_line_break<'s>( +fn compare_line_break<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s LineBreak<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b LineBreak<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2094,11 +2027,11 @@ fn compare_line_break<'s>( .into()) } -fn compare_target<'s>( +fn compare_target<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Target<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Target<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2115,11 +2048,11 @@ fn compare_target<'s>( .into()) } -fn compare_statistics_cookie<'s>( +fn compare_statistics_cookie<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s StatisticsCookie<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b StatisticsCookie<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2136,11 +2069,11 @@ fn compare_statistics_cookie<'s>( .into()) } -fn compare_subscript<'s>( +fn compare_subscript<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Subscript<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Subscript<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2157,11 +2090,11 @@ fn compare_subscript<'s>( .into()) } -fn compare_superscript<'s>( +fn compare_superscript<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Superscript<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Superscript<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; @@ -2178,11 +2111,11 @@ fn compare_superscript<'s>( .into()) } -fn compare_timestamp<'s>( +fn compare_timestamp<'b, 's>( _source: &'s str, - emacs: &'s Token<'s>, - rust: &'s Timestamp<'s>, -) -> Result, Box> { + emacs: &'b Token<'s>, + rust: &'b Timestamp<'s>, +) -> Result, Box> { let this_status = DiffStatus::Good; let message = None; diff --git a/src/compare/elisp_fact.rs b/src/compare/elisp_fact.rs index 4646f7e..6d846e5 100644 --- a/src/compare/elisp_fact.rs +++ b/src/compare/elisp_fact.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use crate::types::AstNode; use crate::types::AngleLink; use crate::types::BabelCall; use crate::types::Bold; @@ -60,21 +61,84 @@ use crate::types::Verbatim; use crate::types::VerseBlock; pub(crate) trait ElispFact<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str>; + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str>; } pub(crate) trait GetElispFact<'s> { - fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s>; + fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s>; } impl<'s, I: ElispFact<'s>> GetElispFact<'s> for I { - fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s> { + fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s> { self } } +impl<'r, 's> GetElispFact<'s> for AstNode<'r, 's> { + fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s> { + match self { + AstNode::Document(inner) => *inner, + AstNode::Heading(inner) => *inner, + AstNode::Section(inner) => *inner, + AstNode::Paragraph(inner) => *inner, + AstNode::PlainList(inner) => *inner, + AstNode::PlainListItem(inner) => *inner, + AstNode::GreaterBlock(inner) => *inner, + AstNode::DynamicBlock(inner) => *inner, + AstNode::FootnoteDefinition(inner) => *inner, + AstNode::Comment(inner) => *inner, + AstNode::Drawer(inner) => *inner, + AstNode::PropertyDrawer(inner) => *inner, + AstNode::NodeProperty(inner) => *inner, + AstNode::Table(inner) => *inner, + AstNode::TableRow(inner) => *inner, + AstNode::VerseBlock(inner) => *inner, + AstNode::CommentBlock(inner) => *inner, + AstNode::ExampleBlock(inner) => *inner, + AstNode::ExportBlock(inner) => *inner, + AstNode::SrcBlock(inner) => *inner, + AstNode::Clock(inner) => *inner, + AstNode::DiarySexp(inner) => *inner, + AstNode::Planning(inner) => *inner, + AstNode::FixedWidthArea(inner) => *inner, + AstNode::HorizontalRule(inner) => *inner, + AstNode::Keyword(inner) => *inner, + AstNode::BabelCall(inner) => *inner, + AstNode::LatexEnvironment(inner) => *inner, + AstNode::Bold(inner) => *inner, + AstNode::Italic(inner) => *inner, + AstNode::Underline(inner) => *inner, + AstNode::StrikeThrough(inner) => *inner, + AstNode::Code(inner) => *inner, + AstNode::Verbatim(inner) => *inner, + AstNode::PlainText(inner) => *inner, + AstNode::RegularLink(inner) => *inner, + AstNode::RadioLink(inner) => *inner, + AstNode::RadioTarget(inner) => *inner, + AstNode::PlainLink(inner) => *inner, + AstNode::AngleLink(inner) => *inner, + AstNode::OrgMacro(inner) => *inner, + AstNode::Entity(inner) => *inner, + AstNode::LatexFragment(inner) => *inner, + AstNode::ExportSnippet(inner) => *inner, + AstNode::FootnoteReference(inner) => *inner, + AstNode::Citation(inner) => *inner, + AstNode::CitationReference(inner) => *inner, + AstNode::InlineBabelCall(inner) => *inner, + AstNode::InlineSourceBlock(inner) => *inner, + AstNode::LineBreak(inner) => *inner, + AstNode::Target(inner) => *inner, + AstNode::StatisticsCookie(inner) => *inner, + AstNode::Subscript(inner) => *inner, + AstNode::Superscript(inner) => *inner, + AstNode::TableCell(inner) => *inner, + AstNode::Timestamp(inner) => *inner, + } + } +} + impl<'s> GetElispFact<'s> for Element<'s> { - fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s> { + fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s> { match self { Element::Paragraph(inner) => inner, Element::PlainList(inner) => inner, @@ -103,7 +167,7 @@ impl<'s> GetElispFact<'s> for Element<'s> { } impl<'s> GetElispFact<'s> for Object<'s> { - fn get_elisp_fact(&'s self) -> &'s dyn ElispFact<'s> { + fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s> { match self { Object::Bold(inner) => inner, Object::Italic(inner) => inner, @@ -137,37 +201,37 @@ impl<'s> GetElispFact<'s> for Object<'s> { } impl<'s> ElispFact<'s> for Document<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "org-data".into() } } impl<'s> ElispFact<'s> for Section<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "section".into() } } impl<'s> ElispFact<'s> for Heading<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "headline".into() } } impl<'s> ElispFact<'s> for PlainList<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "plain-list".into() } } impl<'s> ElispFact<'s> for PlainListItem<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "item".into() } } impl<'s> ElispFact<'s> for GreaterBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { match self.name.to_lowercase().as_str() { "center" => "center-block".into(), "quote" => "quote-block".into(), @@ -177,297 +241,297 @@ impl<'s> ElispFact<'s> for GreaterBlock<'s> { } impl<'s> ElispFact<'s> for DynamicBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "dynamic-block".into() } } impl<'s> ElispFact<'s> for FootnoteDefinition<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "footnote-definition".into() } } impl<'s> ElispFact<'s> for Drawer<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "drawer".into() } } impl<'s> ElispFact<'s> for PropertyDrawer<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "property-drawer".into() } } impl<'s> ElispFact<'s> for NodeProperty<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "node-property".into() } } impl<'s> ElispFact<'s> for Table<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "table".into() } } impl<'s> ElispFact<'s> for TableRow<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "table-row".into() } } impl<'s> ElispFact<'s> for Paragraph<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "paragraph".into() } } impl<'s> ElispFact<'s> for TableCell<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "table-cell".into() } } impl<'s> ElispFact<'s> for Comment<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "comment".into() } } impl<'s> ElispFact<'s> for VerseBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "verse-block".into() } } impl<'s> ElispFact<'s> for CommentBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "comment-block".into() } } impl<'s> ElispFact<'s> for ExampleBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "example-block".into() } } impl<'s> ElispFact<'s> for ExportBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "export-block".into() } } impl<'s> ElispFact<'s> for SrcBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "src-block".into() } } impl<'s> ElispFact<'s> for Clock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "clock".into() } } impl<'s> ElispFact<'s> for DiarySexp<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "diary-sexp".into() } } impl<'s> ElispFact<'s> for Planning<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "planning".into() } } impl<'s> ElispFact<'s> for FixedWidthArea<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "fixed-width".into() } } impl<'s> ElispFact<'s> for HorizontalRule<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "horizontal-rule".into() } } impl<'s> ElispFact<'s> for Keyword<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "keyword".into() } } impl<'s> ElispFact<'s> for BabelCall<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "babel-call".into() } } impl<'s> ElispFact<'s> for LatexEnvironment<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "latex-environment".into() } } impl<'s> ElispFact<'s> for Bold<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "bold".into() } } impl<'s> ElispFact<'s> for Italic<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "italic".into() } } impl<'s> ElispFact<'s> for Underline<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "underline".into() } } impl<'s> ElispFact<'s> for StrikeThrough<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "strike-through".into() } } impl<'s> ElispFact<'s> for Code<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "code".into() } } impl<'s> ElispFact<'s> for Verbatim<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "verbatim".into() } } impl<'s> ElispFact<'s> for RegularLink<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for RadioLink<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for RadioTarget<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "radio-target".into() } } impl<'s> ElispFact<'s> for PlainLink<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for AngleLink<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for OrgMacro<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "macro".into() } } impl<'s> ElispFact<'s> for Entity<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "entity".into() } } impl<'s> ElispFact<'s> for LatexFragment<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "latex-fragment".into() } } impl<'s> ElispFact<'s> for ExportSnippet<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "export-snippet".into() } } impl<'s> ElispFact<'s> for FootnoteReference<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "footnote-reference".into() } } impl<'s> ElispFact<'s> for Citation<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "citation".into() } } impl<'s> ElispFact<'s> for CitationReference<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "citation-reference".into() } } impl<'s> ElispFact<'s> for InlineBabelCall<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "inline-babel-call".into() } } impl<'s> ElispFact<'s> for InlineSourceBlock<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "inline-src-block".into() } } impl<'s> ElispFact<'s> for LineBreak<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "line-break".into() } } impl<'s> ElispFact<'s> for Target<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "target".into() } } impl<'s> ElispFact<'s> for StatisticsCookie<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "statistics-cookie".into() } } impl<'s> ElispFact<'s> for Subscript<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "subscript".into() } } impl<'s> ElispFact<'s> for Superscript<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "superscript".into() } } impl<'s> ElispFact<'s> for Timestamp<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "timestamp".into() } } impl<'s> ElispFact<'s> for PlainText<'s> { - fn get_elisp_name(&'s self) -> Cow<'s, str> { + fn get_elisp_name<'b>(&'b 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/util.rs b/src/compare/util.rs index c770abd..9c001f2 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -16,9 +16,9 @@ fn is_slice_of(parent: &str, child: &str) -> bool { /// Get the byte offset into source that the rust object exists at. /// /// These offsets are zero-based unlike the elisp ones. -fn get_rust_byte_offsets<'s, S: StandardProperties<'s> + ?Sized>( +fn get_rust_byte_offsets<'b, 's, S: StandardProperties<'s> + ?Sized>( original_document: &'s str, - rust_ast_node: &'s S, + rust_ast_node: &'b S, ) -> (usize, usize) { let rust_object_source = rust_ast_node.get_source(); debug_assert!(is_slice_of(original_document, rust_object_source)); @@ -28,20 +28,21 @@ fn get_rust_byte_offsets<'s, S: StandardProperties<'s> + ?Sized>( } pub(crate) fn compare_standard_properties< + 'b, 's, S: GetStandardProperties<'s> + GetElispFact<'s> + ?Sized, >( original_document: &'s str, - emacs: &'s Token<'s>, - rust: &'s S, + emacs: &'b Token<'s>, + rust: &'b 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>, +pub(crate) fn assert_name<'b, 's, S: AsRef>( + emacs: &'b Token<'s>, name: S, ) -> Result<(), Box> { let name = name.as_ref(); @@ -63,10 +64,10 @@ pub(crate) fn assert_name<'s, S: AsRef>( /// Assert that the character ranges defined by upstream org-mode's :standard-properties match the slices in Organic's StandardProperties. /// /// This does **not** handle plain text because plain text is a special case. -pub(crate) fn assert_bounds<'s, S: StandardProperties<'s> + ?Sized>( +pub(crate) fn assert_bounds<'b, 's, S: StandardProperties<'s> + ?Sized>( original_document: &'s str, - emacs: &'s Token<'s>, - rust: &'s S, + emacs: &'b Token<'s>, + rust: &'b S, ) -> Result<(), Box> { let standard_properties = get_emacs_standard_properties(emacs)?; // 1-based let (begin, end) = ( @@ -99,8 +100,8 @@ struct EmacsStandardProperties { post_blank: Option, } -fn get_emacs_standard_properties<'s>( - emacs: &'s Token<'s>, +fn get_emacs_standard_properties<'b, 's>( + emacs: &'b Token<'s>, ) -> Result> { let children = emacs.as_list()?; let attributes_child = children @@ -172,10 +173,10 @@ fn maybe_token_to_usize( /// Returns Ok(None) if value is nil. /// /// Returns error if the attribute is not specified on the token at all. -pub(crate) fn get_property<'s, 'x>( - emacs: &'s Token<'s>, +pub(crate) fn get_property<'b, 's, 'x>( + emacs: &'b Token<'s>, key: &'x str, -) -> Result>, Box> { +) -> Result>, Box> { let children = emacs.as_list()?; let attributes_child = children .iter() @@ -195,8 +196,8 @@ pub(crate) fn get_property<'s, 'x>( /// Get a named property containing an unquoted atom from the emacs token. /// /// Returns None if key is not found. -pub(crate) fn get_property_unquoted_atom<'s, 'x>( - emacs: &'s Token<'s>, +pub(crate) fn get_property_unquoted_atom<'b, 's, 'x>( + emacs: &'b Token<'s>, key: &'x str, ) -> Result, Box> { Ok(get_property(emacs, key)? @@ -207,8 +208,8 @@ pub(crate) fn get_property_unquoted_atom<'s, 'x>( /// Get a named property containing an quoted string from the emacs token. /// /// Returns None if key is not found. -pub(crate) fn get_property_quoted_string<'s, 'x>( - emacs: &'s Token<'s>, +pub(crate) fn get_property_quoted_string<'b, 's, 'x>( + emacs: &'b Token<'s>, key: &'x str, ) -> Result, Box> { Ok(get_property(emacs, key)? @@ -223,8 +224,8 @@ pub(crate) fn get_property_quoted_string<'s, 'x>( /// This uses the elisp convention of nil == false, non-nil == true. /// /// Returns false if key is not found. -pub(crate) fn get_property_boolean<'s, 'x>( - emacs: &'s Token<'s>, +pub(crate) fn get_property_boolean<'b, 's, 'x>( + emacs: &'b Token<'s>, key: &'x str, ) -> Result> { Ok(get_property(emacs, key)? diff --git a/src/iter/all_ast_node_iter.rs b/src/iter/all_ast_node_iter.rs index 1598990..9d6b091 100644 --- a/src/iter/all_ast_node_iter.rs +++ b/src/iter/all_ast_node_iter.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; -use super::ast_node::AstNode; use super::ast_node_iter::AstNodeIter; +use crate::types::AstNode; pub struct AllAstNodeIter<'r, 's> { root: Option>, diff --git a/src/iter/ast_node_iter.rs b/src/iter/ast_node_iter.rs index 6c51c11..2da6e22 100644 --- a/src/iter/ast_node_iter.rs +++ b/src/iter/ast_node_iter.rs @@ -1,10 +1,10 @@ use std::marker::PhantomData; -use super::ast_node::AstNode; use super::macros::children_iter; use super::macros::empty_iter; use super::macros::multi_field_iter; use crate::types::AngleLink; +use crate::types::AstNode; use crate::types::BabelCall; use crate::types::Bold; use crate::types::Citation; diff --git a/src/iter/macros.rs b/src/iter/macros.rs index 3834d1b..f428249 100644 --- a/src/iter/macros.rs +++ b/src/iter/macros.rs @@ -1,16 +1,3 @@ -/// Write the implementation of From<> to convert a borrow of the type to an AstNode -macro_rules! to_ast_node { - ($inp:ty, $enum:expr) => { - impl<'r, 's> From<$inp> for AstNode<'r, 's> { - fn from(value: $inp) -> Self { - $enum(value) - } - } - }; -} - -pub(crate) use to_ast_node; - /// Create iterators for ast nodes where it only has to iterate over children macro_rules! children_iter { ($astnodetype:ty, $itertype:ident, $innertype:ty) => { diff --git a/src/iter/mod.rs b/src/iter/mod.rs index d820847..af77bd6 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -1,5 +1,3 @@ mod all_ast_node_iter; -mod ast_node; mod ast_node_iter; mod macros; -pub(crate) use ast_node::AstNode; diff --git a/src/parser/document.rs b/src/parser/document.rs index f71aaee..a7b8b8b 100644 --- a/src/parser/document.rs +++ b/src/parser/document.rs @@ -20,7 +20,7 @@ use crate::context::RefContext; use crate::error::CustomError; use crate::error::MyError; use crate::error::Res; -use crate::iter::AstNode; +use crate::types::AstNode; use crate::parser::org_source::convert_error; use crate::parser::util::blank_line; use crate::types::Document; diff --git a/src/parser/in_buffer_settings.rs b/src/parser/in_buffer_settings.rs index 3586d2f..95618e1 100644 --- a/src/parser/in_buffer_settings.rs +++ b/src/parser/in_buffer_settings.rs @@ -11,7 +11,7 @@ use super::OrgSource; use crate::context::HeadlineLevelFilter; use crate::error::CustomError; use crate::error::Res; -use crate::iter::AstNode; +use crate::types::AstNode; use crate::settings::GlobalSettings; use crate::types::Document; use crate::types::Keyword; diff --git a/src/iter/ast_node.rs b/src/types/ast_node.rs similarity index 77% rename from src/iter/ast_node.rs rename to src/types/ast_node.rs index 0efae5f..e925f74 100644 --- a/src/iter/ast_node.rs +++ b/src/types/ast_node.rs @@ -21,6 +21,7 @@ use crate::types::ExportSnippet; use crate::types::FixedWidthArea; use crate::types::FootnoteDefinition; use crate::types::FootnoteReference; +use crate::types::GetStandardProperties; use crate::types::GreaterBlock; use crate::types::Heading; use crate::types::HorizontalRule; @@ -249,3 +250,66 @@ to_ast_node!(&'r Subscript<'s>, AstNode::Subscript); to_ast_node!(&'r Superscript<'s>, AstNode::Superscript); to_ast_node!(&'r TableCell<'s>, AstNode::TableCell); to_ast_node!(&'r Timestamp<'s>, AstNode::Timestamp); + +impl<'r, 's> GetStandardProperties<'s> for AstNode<'r, 's> { + fn get_standard_properties<'b>(&'b self) -> &'b dyn crate::types::StandardProperties<'s> { + match self { + AstNode::Document(inner) => *inner, + AstNode::Heading(inner) => *inner, + AstNode::Section(inner) => *inner, + AstNode::Paragraph(inner) => *inner, + AstNode::PlainList(inner) => *inner, + AstNode::PlainListItem(inner) => *inner, + AstNode::GreaterBlock(inner) => *inner, + AstNode::DynamicBlock(inner) => *inner, + AstNode::FootnoteDefinition(inner) => *inner, + AstNode::Comment(inner) => *inner, + AstNode::Drawer(inner) => *inner, + AstNode::PropertyDrawer(inner) => *inner, + AstNode::NodeProperty(inner) => *inner, + AstNode::Table(inner) => *inner, + AstNode::TableRow(inner) => *inner, + AstNode::VerseBlock(inner) => *inner, + AstNode::CommentBlock(inner) => *inner, + AstNode::ExampleBlock(inner) => *inner, + AstNode::ExportBlock(inner) => *inner, + AstNode::SrcBlock(inner) => *inner, + AstNode::Clock(inner) => *inner, + AstNode::DiarySexp(inner) => *inner, + AstNode::Planning(inner) => *inner, + AstNode::FixedWidthArea(inner) => *inner, + AstNode::HorizontalRule(inner) => *inner, + AstNode::Keyword(inner) => *inner, + AstNode::BabelCall(inner) => *inner, + AstNode::LatexEnvironment(inner) => *inner, + AstNode::Bold(inner) => *inner, + AstNode::Italic(inner) => *inner, + AstNode::Underline(inner) => *inner, + AstNode::StrikeThrough(inner) => *inner, + AstNode::Code(inner) => *inner, + AstNode::Verbatim(inner) => *inner, + AstNode::PlainText(inner) => *inner, + AstNode::RegularLink(inner) => *inner, + AstNode::RadioLink(inner) => *inner, + AstNode::RadioTarget(inner) => *inner, + AstNode::PlainLink(inner) => *inner, + AstNode::AngleLink(inner) => *inner, + AstNode::OrgMacro(inner) => *inner, + AstNode::Entity(inner) => *inner, + AstNode::LatexFragment(inner) => *inner, + AstNode::ExportSnippet(inner) => *inner, + AstNode::FootnoteReference(inner) => *inner, + AstNode::Citation(inner) => *inner, + AstNode::CitationReference(inner) => *inner, + AstNode::InlineBabelCall(inner) => *inner, + AstNode::InlineSourceBlock(inner) => *inner, + AstNode::LineBreak(inner) => *inner, + AstNode::Target(inner) => *inner, + AstNode::StatisticsCookie(inner) => *inner, + AstNode::Subscript(inner) => *inner, + AstNode::Superscript(inner) => *inner, + AstNode::TableCell(inner) => *inner, + AstNode::Timestamp(inner) => *inner, + } + } +} diff --git a/src/types/document.rs b/src/types/document.rs index 6066873..31f471c 100644 --- a/src/types/document.rs +++ b/src/types/document.rs @@ -50,7 +50,7 @@ pub enum TodoKeywordType { } impl<'s> GetStandardProperties<'s> for DocumentElement<'s> { - fn get_standard_properties(&'s self) -> &'s dyn StandardProperties { + fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> { match self { DocumentElement::Heading(inner) => inner, DocumentElement::Section(inner) => inner, @@ -59,19 +59,19 @@ impl<'s> GetStandardProperties<'s> for DocumentElement<'s> { } impl<'s> StandardProperties<'s> for Document<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Section<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Heading<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } diff --git a/src/types/element.rs b/src/types/element.rs index a5c472c..020b2d1 100644 --- a/src/types/element.rs +++ b/src/types/element.rs @@ -81,7 +81,7 @@ impl<'s> SetSource<'s> for Element<'s> { } impl<'s> GetStandardProperties<'s> for Element<'s> { - fn get_standard_properties(&'s self) -> &'s dyn StandardProperties { + fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> { match self { Element::Paragraph(inner) => inner, Element::PlainList(inner) => inner, diff --git a/src/types/get_standard_properties.rs b/src/types/get_standard_properties.rs index 3488d30..ae6464b 100644 --- a/src/types/get_standard_properties.rs +++ b/src/types/get_standard_properties.rs @@ -2,11 +2,11 @@ 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; + fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s>; } impl<'s, I: StandardProperties<'s>> GetStandardProperties<'s> for I { - fn get_standard_properties(&'s self) -> &'s dyn StandardProperties { + fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> { self } } diff --git a/src/types/greater_element.rs b/src/types/greater_element.rs index 85f4c57..9285d98 100644 --- a/src/types/greater_element.rs +++ b/src/types/greater_element.rs @@ -99,61 +99,61 @@ pub struct TableRow<'s> { } impl<'s> StandardProperties<'s> for PlainList<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for PlainListItem<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for GreaterBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for DynamicBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for FootnoteDefinition<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Drawer<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for PropertyDrawer<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for NodeProperty<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Table<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for TableRow<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } diff --git a/src/types/lesser_element.rs b/src/types/lesser_element.rs index 80c3d51..1061139 100644 --- a/src/types/lesser_element.rs +++ b/src/types/lesser_element.rs @@ -115,93 +115,93 @@ impl<'s> Paragraph<'s> { } impl<'s> StandardProperties<'s> for Paragraph<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for TableCell<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Comment<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for VerseBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for CommentBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for ExampleBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for ExportBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for SrcBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Clock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for DiarySexp<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Planning<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for FixedWidthArea<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for HorizontalRule<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Keyword<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for BabelCall<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for LatexEnvironment<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } diff --git a/src/types/macros.rs b/src/types/macros.rs new file mode 100644 index 0000000..a718a0e --- /dev/null +++ b/src/types/macros.rs @@ -0,0 +1,12 @@ +/// Write the implementation of From<> to convert a borrow of the type to an AstNode +macro_rules! to_ast_node { + ($inp:ty, $enum:expr) => { + impl<'r, 's> From<$inp> for AstNode<'r, 's> { + fn from(value: $inp) -> Self { + $enum(value) + } + } + }; +} + +pub(crate) use to_ast_node; diff --git a/src/types/mod.rs b/src/types/mod.rs index 7976ecd..6f41156 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -1,11 +1,14 @@ +mod ast_node; mod document; mod element; mod get_standard_properties; mod greater_element; mod lesser_element; +mod macros; mod object; mod source; mod standard_properties; +pub(crate) use ast_node::AstNode; pub use document::Document; pub use document::DocumentElement; pub use document::Heading; diff --git a/src/types/object.rs b/src/types/object.rs index 11a07f7..2d8e06e 100644 --- a/src/types/object.rs +++ b/src/types/object.rs @@ -187,7 +187,7 @@ pub struct Timestamp<'s> { } impl<'s> GetStandardProperties<'s> for Object<'s> { - fn get_standard_properties(&'s self) -> &'s dyn StandardProperties { + fn get_standard_properties<'b>(&'b self) -> &'b dyn StandardProperties<'s> { match self { Object::Bold(inner) => inner, Object::Italic(inner) => inner, @@ -221,163 +221,163 @@ impl<'s> GetStandardProperties<'s> for Object<'s> { } impl<'s> StandardProperties<'s> for Bold<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Italic<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Underline<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for StrikeThrough<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Code<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Verbatim<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for RegularLink<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for RadioLink<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for RadioTarget<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for PlainLink<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for AngleLink<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for OrgMacro<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Entity<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for LatexFragment<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for ExportSnippet<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for FootnoteReference<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Citation<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for CitationReference<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for InlineBabelCall<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for InlineSourceBlock<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for LineBreak<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Target<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for StatisticsCookie<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Subscript<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Superscript<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for Timestamp<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } impl<'s> StandardProperties<'s> for PlainText<'s> { - fn get_source(&'s self) -> &'s str { + fn get_source<'b>(&'b self) -> &'s str { self.source } } diff --git a/src/types/standard_properties.rs b/src/types/standard_properties.rs index f6a3987..aa57962 100644 --- a/src/types/standard_properties.rs +++ b/src/types/standard_properties.rs @@ -3,7 +3,7 @@ pub trait StandardProperties<'s> { /// Get the slice of the entire AST node. /// /// This corresponds to :begin to :end in upstream org-mode's standard properties. - fn get_source(&'s self) -> &'s str; + fn get_source<'b>(&'b self) -> &'s str; // Get the slice of the AST node's contents. //