diff --git a/src/compare/diff.rs b/src/compare/diff.rs index bf3dba27..0861c322 100644 --- a/src/compare/diff.rs +++ b/src/compare/diff.rs @@ -363,7 +363,33 @@ fn compare_ast_node<'b, 's>( AstNode::TableCell(_) => todo!(), AstNode::Timestamp(node) => compare_timestamp(source, emacs, node), }; - todo!() + + 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_element<'b, 's>( diff --git a/src/compare/elisp_fact.rs b/src/compare/elisp_fact.rs index 1729f2eb..abe20ef5 100644 --- a/src/compare/elisp_fact.rs +++ b/src/compare/elisp_fact.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; +use crate::iter::AstNode; use crate::types::AngleLink; use crate::types::BabelCall; use crate::types::Bold; @@ -73,6 +74,69 @@ impl<'s, I: ElispFact<'s>> GetElispFact<'s> for I { } } +impl<'r, 's> GetElispFact<'s> for AstNode<'r, 's> { + fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s> { + match self { + AstNode::Document(_) => todo!(), + AstNode::Heading(_) => todo!(), + AstNode::Section(_) => todo!(), + AstNode::Paragraph(_) => todo!(), + AstNode::PlainList(_) => todo!(), + AstNode::PlainListItem(_) => todo!(), + AstNode::GreaterBlock(_) => todo!(), + AstNode::DynamicBlock(_) => todo!(), + AstNode::FootnoteDefinition(_) => todo!(), + AstNode::Comment(_) => todo!(), + AstNode::Drawer(_) => todo!(), + AstNode::PropertyDrawer(_) => todo!(), + AstNode::NodeProperty(_) => todo!(), + AstNode::Table(_) => todo!(), + AstNode::TableRow(_) => todo!(), + AstNode::VerseBlock(_) => todo!(), + AstNode::CommentBlock(_) => todo!(), + AstNode::ExampleBlock(_) => todo!(), + AstNode::ExportBlock(_) => todo!(), + AstNode::SrcBlock(_) => todo!(), + AstNode::Clock(_) => todo!(), + AstNode::DiarySexp(_) => todo!(), + AstNode::Planning(_) => todo!(), + AstNode::FixedWidthArea(_) => todo!(), + AstNode::HorizontalRule(_) => todo!(), + AstNode::Keyword(_) => todo!(), + AstNode::BabelCall(_) => todo!(), + AstNode::LatexEnvironment(_) => todo!(), + AstNode::Bold(_) => todo!(), + AstNode::Italic(_) => todo!(), + AstNode::Underline(_) => todo!(), + AstNode::StrikeThrough(_) => todo!(), + AstNode::Code(_) => todo!(), + AstNode::Verbatim(_) => todo!(), + AstNode::PlainText(_) => todo!(), + AstNode::RegularLink(_) => todo!(), + AstNode::RadioLink(_) => todo!(), + AstNode::RadioTarget(_) => todo!(), + AstNode::PlainLink(_) => todo!(), + AstNode::AngleLink(_) => todo!(), + AstNode::OrgMacro(_) => todo!(), + AstNode::Entity(_) => todo!(), + AstNode::LatexFragment(_) => todo!(), + AstNode::ExportSnippet(_) => todo!(), + AstNode::FootnoteReference(_) => todo!(), + AstNode::Citation(_) => todo!(), + AstNode::CitationReference(_) => todo!(), + AstNode::InlineBabelCall(_) => todo!(), + AstNode::InlineSourceBlock(_) => todo!(), + AstNode::LineBreak(_) => todo!(), + AstNode::Target(_) => todo!(), + AstNode::StatisticsCookie(_) => todo!(), + AstNode::Subscript(_) => todo!(), + AstNode::Superscript(_) => todo!(), + AstNode::TableCell(_) => todo!(), + AstNode::Timestamp(inner) => *inner, + } + } +} + impl<'s> GetElispFact<'s> for Element<'s> { fn get_elisp_fact<'b>(&'b self) -> &'b dyn ElispFact<'s> { match self { diff --git a/src/compare/util.rs b/src/compare/util.rs index c770abd7..b57a92fe 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,12 +28,13 @@ 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())?; @@ -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) = ( diff --git a/src/iter/ast_node.rs b/src/iter/ast_node.rs index 0efae5f7..2de57428 100644 --- a/src/iter/ast_node.rs +++ b/src/iter/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(_) => todo!(), + AstNode::Heading(_) => todo!(), + AstNode::Section(_) => todo!(), + AstNode::Paragraph(_) => todo!(), + AstNode::PlainList(_) => todo!(), + AstNode::PlainListItem(_) => todo!(), + AstNode::GreaterBlock(_) => todo!(), + AstNode::DynamicBlock(_) => todo!(), + AstNode::FootnoteDefinition(_) => todo!(), + AstNode::Comment(_) => todo!(), + AstNode::Drawer(_) => todo!(), + AstNode::PropertyDrawer(_) => todo!(), + AstNode::NodeProperty(_) => todo!(), + AstNode::Table(_) => todo!(), + AstNode::TableRow(_) => todo!(), + AstNode::VerseBlock(_) => todo!(), + AstNode::CommentBlock(_) => todo!(), + AstNode::ExampleBlock(_) => todo!(), + AstNode::ExportBlock(_) => todo!(), + AstNode::SrcBlock(_) => todo!(), + AstNode::Clock(_) => todo!(), + AstNode::DiarySexp(_) => todo!(), + AstNode::Planning(_) => todo!(), + AstNode::FixedWidthArea(_) => todo!(), + AstNode::HorizontalRule(_) => todo!(), + AstNode::Keyword(_) => todo!(), + AstNode::BabelCall(_) => todo!(), + AstNode::LatexEnvironment(_) => todo!(), + AstNode::Bold(_) => todo!(), + AstNode::Italic(_) => todo!(), + AstNode::Underline(_) => todo!(), + AstNode::StrikeThrough(_) => todo!(), + AstNode::Code(_) => todo!(), + AstNode::Verbatim(_) => todo!(), + AstNode::PlainText(_) => todo!(), + AstNode::RegularLink(_) => todo!(), + AstNode::RadioLink(_) => todo!(), + AstNode::RadioTarget(_) => todo!(), + AstNode::PlainLink(_) => todo!(), + AstNode::AngleLink(_) => todo!(), + AstNode::OrgMacro(_) => todo!(), + AstNode::Entity(_) => todo!(), + AstNode::LatexFragment(_) => todo!(), + AstNode::ExportSnippet(_) => todo!(), + AstNode::FootnoteReference(_) => todo!(), + AstNode::Citation(_) => todo!(), + AstNode::CitationReference(_) => todo!(), + AstNode::InlineBabelCall(_) => todo!(), + AstNode::InlineSourceBlock(_) => todo!(), + AstNode::LineBreak(_) => todo!(), + AstNode::Target(_) => todo!(), + AstNode::StatisticsCookie(_) => todo!(), + AstNode::Subscript(_) => todo!(), + AstNode::Superscript(_) => todo!(), + AstNode::TableCell(_) => todo!(), + AstNode::Timestamp(inner) => *inner, + } + } +}