Unify the standard properties checks in diff.
Instead of copy+pasting them into each compare function, we now call a shared function from a handful of places.
This commit is contained in:
		
							parent
							
								
									dd8a8207ce
								
							
						
					
					
						commit
						d5b1014fe4
					
				
							
								
								
									
										1066
									
								
								src/compare/diff.rs
									
									
									
									
									
								
							
							
						
						
									
										1066
									
								
								src/compare/diff.rs
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										474
									
								
								src/compare/elisp_fact.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										474
									
								
								src/compare/elisp_fact.rs
									
									
									
									
									
										Normal file
									
								
							| @ -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() | ||||
|     } | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| mod compare; | ||||
| mod diff; | ||||
| mod elisp_fact; | ||||
| mod parse; | ||||
| mod sexp; | ||||
| mod util; | ||||
|  | ||||
| @ -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<dyn std::error::Error>> { | ||||
|     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<str>>( | ||||
|     emacs: &'s Token<'s>, | ||||
|     name: S, | ||||
| ) -> Result<(), Box<dyn std::error::Error>> { | ||||
|     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 | ||||
|         ))?; | ||||
|  | ||||
| @ -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<OrgSource<'s>, Keyword<'s>> { | ||||
|     filtered_keyword(babel_call_key)(input) | ||||
| ) -> Res<OrgSource<'s>, 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"))] | ||||
|  | ||||
| @ -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>), | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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 { | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Tom Alexander
						Tom Alexander