use std::borrow::Cow; use crate::iter::AstNode; 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<'b>(&'b self) -> Cow<'s, str>; } pub(crate) trait GetElispFact<'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<'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(_) => 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 { 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<'b>(&'b self) -> &'b 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<'b>(&'b self) -> Cow<'s, str> { "org-data".into() } } impl<'s> ElispFact<'s> for Section<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "section".into() } } impl<'s> ElispFact<'s> for Heading<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "headline".into() } } impl<'s> ElispFact<'s> for PlainList<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "plain-list".into() } } impl<'s> ElispFact<'s> for PlainListItem<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "item".into() } } impl<'s> ElispFact<'s> for GreaterBlock<'s> { 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(), _ => "special-block".into(), } } } impl<'s> ElispFact<'s> for DynamicBlock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "dynamic-block".into() } } impl<'s> ElispFact<'s> for FootnoteDefinition<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "footnote-definition".into() } } impl<'s> ElispFact<'s> for Drawer<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "drawer".into() } } impl<'s> ElispFact<'s> for PropertyDrawer<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "property-drawer".into() } } impl<'s> ElispFact<'s> for NodeProperty<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "node-property".into() } } impl<'s> ElispFact<'s> for Table<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "table".into() } } impl<'s> ElispFact<'s> for TableRow<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "table-row".into() } } impl<'s> ElispFact<'s> for Paragraph<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "paragraph".into() } } impl<'s> ElispFact<'s> for TableCell<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "table-cell".into() } } impl<'s> ElispFact<'s> for Comment<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "comment".into() } } impl<'s> ElispFact<'s> for VerseBlock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "verse-block".into() } } impl<'s> ElispFact<'s> for CommentBlock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "comment-block".into() } } impl<'s> ElispFact<'s> for ExampleBlock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "example-block".into() } } impl<'s> ElispFact<'s> for ExportBlock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "export-block".into() } } impl<'s> ElispFact<'s> for SrcBlock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "src-block".into() } } impl<'s> ElispFact<'s> for Clock<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "clock".into() } } impl<'s> ElispFact<'s> for DiarySexp<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "diary-sexp".into() } } impl<'s> ElispFact<'s> for Planning<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "planning".into() } } impl<'s> ElispFact<'s> for FixedWidthArea<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "fixed-width".into() } } impl<'s> ElispFact<'s> for HorizontalRule<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "horizontal-rule".into() } } impl<'s> ElispFact<'s> for Keyword<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "keyword".into() } } impl<'s> ElispFact<'s> for BabelCall<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "babel-call".into() } } impl<'s> ElispFact<'s> for LatexEnvironment<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "latex-environment".into() } } impl<'s> ElispFact<'s> for Bold<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "bold".into() } } impl<'s> ElispFact<'s> for Italic<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "italic".into() } } impl<'s> ElispFact<'s> for Underline<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "underline".into() } } impl<'s> ElispFact<'s> for StrikeThrough<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "strike-through".into() } } impl<'s> ElispFact<'s> for Code<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "code".into() } } impl<'s> ElispFact<'s> for Verbatim<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "verbatim".into() } } impl<'s> ElispFact<'s> for RegularLink<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for RadioLink<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for RadioTarget<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "radio-target".into() } } impl<'s> ElispFact<'s> for PlainLink<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for AngleLink<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "link".into() } } impl<'s> ElispFact<'s> for OrgMacro<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "macro".into() } } impl<'s> ElispFact<'s> for Entity<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "entity".into() } } impl<'s> ElispFact<'s> for LatexFragment<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "latex-fragment".into() } } impl<'s> ElispFact<'s> for ExportSnippet<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "export-snippet".into() } } impl<'s> ElispFact<'s> for FootnoteReference<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "footnote-reference".into() } } impl<'s> ElispFact<'s> for Citation<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "citation".into() } } impl<'s> ElispFact<'s> for CitationReference<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "citation-reference".into() } } impl<'s> ElispFact<'s> for InlineBabelCall<'s> { 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<'b>(&'b self) -> Cow<'s, str> { "inline-src-block".into() } } impl<'s> ElispFact<'s> for LineBreak<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "line-break".into() } } impl<'s> ElispFact<'s> for Target<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "target".into() } } impl<'s> ElispFact<'s> for StatisticsCookie<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "statistics-cookie".into() } } impl<'s> ElispFact<'s> for Subscript<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "subscript".into() } } impl<'s> ElispFact<'s> for Superscript<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "superscript".into() } } impl<'s> ElispFact<'s> for Timestamp<'s> { fn get_elisp_name<'b>(&'b self) -> Cow<'s, str> { "timestamp".into() } } impl<'s> ElispFact<'s> for PlainText<'s> { 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() } }