Merge branch 'reduce_heap_iter'
This commit is contained in:
commit
a5b4eb40f6
102
src/iter/all_ast_node_iter.rs
Normal file
102
src/iter/all_ast_node_iter.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use super::ast_node::AstNode;
|
||||||
|
use super::ast_node_iter::AstNodeIter;
|
||||||
|
|
||||||
|
pub struct AllAstNodeIter<'r, 's> {
|
||||||
|
root: Option<AstNode<'r, 's>>,
|
||||||
|
queue: VecDeque<AstNodeIter<'r, 's>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> Iterator for AllAstNodeIter<'r, 's> {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if let Some(root) = self.root.take() {
|
||||||
|
self.queue.push_back(AstNodeIter::from_ast_node(&root));
|
||||||
|
return Some(root);
|
||||||
|
}
|
||||||
|
while let Some(child) = self.queue.front_mut() {
|
||||||
|
let next_elem_this_iter = match child {
|
||||||
|
AstNodeIter::Document(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Heading(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Section(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Paragraph(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::PlainList(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::PlainListItem(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::GreaterBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::DynamicBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::FootnoteDefinition(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Comment(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Drawer(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::PropertyDrawer(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::NodeProperty(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Table(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::TableRow(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::VerseBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::CommentBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::ExampleBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::ExportBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::SrcBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Clock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::DiarySexp(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Planning(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::FixedWidthArea(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::HorizontalRule(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Keyword(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::BabelCall(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::LatexEnvironment(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Bold(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Italic(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Underline(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::StrikeThrough(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Code(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Verbatim(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::PlainText(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::RegularLink(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::RadioLink(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::RadioTarget(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::PlainLink(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::AngleLink(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::OrgMacro(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Entity(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::LatexFragment(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::ExportSnippet(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::FootnoteReference(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Citation(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::CitationReference(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::InlineBabelCall(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::InlineSourceBlock(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::LineBreak(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Target(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::StatisticsCookie(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Subscript(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Superscript(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::TableCell(ref mut i) => i.next(),
|
||||||
|
AstNodeIter::Timestamp(ref mut i) => i.next(),
|
||||||
|
};
|
||||||
|
if let Some(next_elem_this_iter) = next_elem_this_iter {
|
||||||
|
self.queue
|
||||||
|
.push_back(AstNodeIter::from_ast_node(&next_elem_this_iter));
|
||||||
|
return Some(next_elem_this_iter);
|
||||||
|
} else {
|
||||||
|
self.queue.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> IntoIterator for AstNode<'r, 's> {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
type IntoIter = AllAstNodeIter<'r, 's>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
AllAstNodeIter {
|
||||||
|
root: Some(self),
|
||||||
|
queue: VecDeque::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
251
src/iter/ast_node.rs
Normal file
251
src/iter/ast_node.rs
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
use super::macros::to_ast_node;
|
||||||
|
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::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;
|
||||||
|
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 enum AstNode<'r, 's> {
|
||||||
|
// Document Nodes
|
||||||
|
Document(&'r Document<'s>),
|
||||||
|
Heading(&'r Heading<'s>),
|
||||||
|
Section(&'r Section<'s>),
|
||||||
|
// Elements
|
||||||
|
Paragraph(&'r Paragraph<'s>),
|
||||||
|
PlainList(&'r PlainList<'s>),
|
||||||
|
PlainListItem(&'r PlainListItem<'s>),
|
||||||
|
GreaterBlock(&'r GreaterBlock<'s>),
|
||||||
|
DynamicBlock(&'r DynamicBlock<'s>),
|
||||||
|
FootnoteDefinition(&'r FootnoteDefinition<'s>),
|
||||||
|
Comment(&'r Comment<'s>),
|
||||||
|
Drawer(&'r Drawer<'s>),
|
||||||
|
PropertyDrawer(&'r PropertyDrawer<'s>),
|
||||||
|
NodeProperty(&'r NodeProperty<'s>),
|
||||||
|
Table(&'r Table<'s>),
|
||||||
|
TableRow(&'r TableRow<'s>),
|
||||||
|
VerseBlock(&'r VerseBlock<'s>),
|
||||||
|
CommentBlock(&'r CommentBlock<'s>),
|
||||||
|
ExampleBlock(&'r ExampleBlock<'s>),
|
||||||
|
ExportBlock(&'r ExportBlock<'s>),
|
||||||
|
SrcBlock(&'r SrcBlock<'s>),
|
||||||
|
Clock(&'r Clock<'s>),
|
||||||
|
DiarySexp(&'r DiarySexp<'s>),
|
||||||
|
Planning(&'r Planning<'s>),
|
||||||
|
FixedWidthArea(&'r FixedWidthArea<'s>),
|
||||||
|
HorizontalRule(&'r HorizontalRule<'s>),
|
||||||
|
Keyword(&'r Keyword<'s>),
|
||||||
|
BabelCall(&'r BabelCall<'s>),
|
||||||
|
LatexEnvironment(&'r LatexEnvironment<'s>),
|
||||||
|
// Objects
|
||||||
|
Bold(&'r Bold<'s>),
|
||||||
|
Italic(&'r Italic<'s>),
|
||||||
|
Underline(&'r Underline<'s>),
|
||||||
|
StrikeThrough(&'r StrikeThrough<'s>),
|
||||||
|
Code(&'r Code<'s>),
|
||||||
|
Verbatim(&'r Verbatim<'s>),
|
||||||
|
PlainText(&'r PlainText<'s>),
|
||||||
|
RegularLink(&'r RegularLink<'s>),
|
||||||
|
RadioLink(&'r RadioLink<'s>),
|
||||||
|
RadioTarget(&'r RadioTarget<'s>),
|
||||||
|
PlainLink(&'r PlainLink<'s>),
|
||||||
|
AngleLink(&'r AngleLink<'s>),
|
||||||
|
OrgMacro(&'r OrgMacro<'s>),
|
||||||
|
Entity(&'r Entity<'s>),
|
||||||
|
LatexFragment(&'r LatexFragment<'s>),
|
||||||
|
ExportSnippet(&'r ExportSnippet<'s>),
|
||||||
|
FootnoteReference(&'r FootnoteReference<'s>),
|
||||||
|
Citation(&'r Citation<'s>),
|
||||||
|
CitationReference(&'r CitationReference<'s>),
|
||||||
|
InlineBabelCall(&'r InlineBabelCall<'s>),
|
||||||
|
InlineSourceBlock(&'r InlineSourceBlock<'s>),
|
||||||
|
LineBreak(&'r LineBreak<'s>),
|
||||||
|
Target(&'r Target<'s>),
|
||||||
|
StatisticsCookie(&'r StatisticsCookie<'s>),
|
||||||
|
Subscript(&'r Subscript<'s>),
|
||||||
|
Superscript(&'r Superscript<'s>),
|
||||||
|
TableCell(&'r TableCell<'s>),
|
||||||
|
Timestamp(&'r Timestamp<'s>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> From<&'r DocumentElement<'s>> for AstNode<'r, 's> {
|
||||||
|
fn from(value: &'r DocumentElement<'s>) -> Self {
|
||||||
|
match value {
|
||||||
|
DocumentElement::Heading(inner) => inner.into(),
|
||||||
|
DocumentElement::Section(inner) => inner.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> From<&'r Element<'s>> for AstNode<'r, 's> {
|
||||||
|
fn from(value: &'r Element<'s>) -> Self {
|
||||||
|
match value {
|
||||||
|
Element::Paragraph(inner) => inner.into(),
|
||||||
|
Element::PlainList(inner) => inner.into(),
|
||||||
|
Element::GreaterBlock(inner) => inner.into(),
|
||||||
|
Element::DynamicBlock(inner) => inner.into(),
|
||||||
|
Element::FootnoteDefinition(inner) => inner.into(),
|
||||||
|
Element::Comment(inner) => inner.into(),
|
||||||
|
Element::Drawer(inner) => inner.into(),
|
||||||
|
Element::PropertyDrawer(inner) => inner.into(),
|
||||||
|
Element::Table(inner) => inner.into(),
|
||||||
|
Element::VerseBlock(inner) => inner.into(),
|
||||||
|
Element::CommentBlock(inner) => inner.into(),
|
||||||
|
Element::ExampleBlock(inner) => inner.into(),
|
||||||
|
Element::ExportBlock(inner) => inner.into(),
|
||||||
|
Element::SrcBlock(inner) => inner.into(),
|
||||||
|
Element::Clock(inner) => inner.into(),
|
||||||
|
Element::DiarySexp(inner) => inner.into(),
|
||||||
|
Element::Planning(inner) => inner.into(),
|
||||||
|
Element::FixedWidthArea(inner) => inner.into(),
|
||||||
|
Element::HorizontalRule(inner) => inner.into(),
|
||||||
|
Element::Keyword(inner) => inner.into(),
|
||||||
|
Element::BabelCall(inner) => inner.into(),
|
||||||
|
Element::LatexEnvironment(inner) => inner.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> From<&'r Object<'s>> for AstNode<'r, 's> {
|
||||||
|
fn from(value: &'r Object<'s>) -> Self {
|
||||||
|
match value {
|
||||||
|
Object::Bold(inner) => inner.into(),
|
||||||
|
Object::Italic(inner) => inner.into(),
|
||||||
|
Object::Underline(inner) => inner.into(),
|
||||||
|
Object::StrikeThrough(inner) => inner.into(),
|
||||||
|
Object::Code(inner) => inner.into(),
|
||||||
|
Object::Verbatim(inner) => inner.into(),
|
||||||
|
Object::PlainText(inner) => inner.into(),
|
||||||
|
Object::RegularLink(inner) => inner.into(),
|
||||||
|
Object::RadioLink(inner) => inner.into(),
|
||||||
|
Object::RadioTarget(inner) => inner.into(),
|
||||||
|
Object::PlainLink(inner) => inner.into(),
|
||||||
|
Object::AngleLink(inner) => inner.into(),
|
||||||
|
Object::OrgMacro(inner) => inner.into(),
|
||||||
|
Object::Entity(inner) => inner.into(),
|
||||||
|
Object::LatexFragment(inner) => inner.into(),
|
||||||
|
Object::ExportSnippet(inner) => inner.into(),
|
||||||
|
Object::FootnoteReference(inner) => inner.into(),
|
||||||
|
Object::Citation(inner) => inner.into(),
|
||||||
|
Object::CitationReference(inner) => inner.into(),
|
||||||
|
Object::InlineBabelCall(inner) => inner.into(),
|
||||||
|
Object::InlineSourceBlock(inner) => inner.into(),
|
||||||
|
Object::LineBreak(inner) => inner.into(),
|
||||||
|
Object::Target(inner) => inner.into(),
|
||||||
|
Object::StatisticsCookie(inner) => inner.into(),
|
||||||
|
Object::Subscript(inner) => inner.into(),
|
||||||
|
Object::Superscript(inner) => inner.into(),
|
||||||
|
Object::Timestamp(inner) => inner.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_ast_node!(&'r Document<'s>, AstNode::Document);
|
||||||
|
to_ast_node!(&'r Heading<'s>, AstNode::Heading);
|
||||||
|
to_ast_node!(&'r Section<'s>, AstNode::Section);
|
||||||
|
to_ast_node!(&'r Paragraph<'s>, AstNode::Paragraph);
|
||||||
|
to_ast_node!(&'r PlainList<'s>, AstNode::PlainList);
|
||||||
|
to_ast_node!(&'r PlainListItem<'s>, AstNode::PlainListItem);
|
||||||
|
to_ast_node!(&'r GreaterBlock<'s>, AstNode::GreaterBlock);
|
||||||
|
to_ast_node!(&'r DynamicBlock<'s>, AstNode::DynamicBlock);
|
||||||
|
to_ast_node!(&'r FootnoteDefinition<'s>, AstNode::FootnoteDefinition);
|
||||||
|
to_ast_node!(&'r Comment<'s>, AstNode::Comment);
|
||||||
|
to_ast_node!(&'r Drawer<'s>, AstNode::Drawer);
|
||||||
|
to_ast_node!(&'r PropertyDrawer<'s>, AstNode::PropertyDrawer);
|
||||||
|
to_ast_node!(&'r NodeProperty<'s>, AstNode::NodeProperty);
|
||||||
|
to_ast_node!(&'r Table<'s>, AstNode::Table);
|
||||||
|
to_ast_node!(&'r TableRow<'s>, AstNode::TableRow);
|
||||||
|
to_ast_node!(&'r VerseBlock<'s>, AstNode::VerseBlock);
|
||||||
|
to_ast_node!(&'r CommentBlock<'s>, AstNode::CommentBlock);
|
||||||
|
to_ast_node!(&'r ExampleBlock<'s>, AstNode::ExampleBlock);
|
||||||
|
to_ast_node!(&'r ExportBlock<'s>, AstNode::ExportBlock);
|
||||||
|
to_ast_node!(&'r SrcBlock<'s>, AstNode::SrcBlock);
|
||||||
|
to_ast_node!(&'r Clock<'s>, AstNode::Clock);
|
||||||
|
to_ast_node!(&'r DiarySexp<'s>, AstNode::DiarySexp);
|
||||||
|
to_ast_node!(&'r Planning<'s>, AstNode::Planning);
|
||||||
|
to_ast_node!(&'r FixedWidthArea<'s>, AstNode::FixedWidthArea);
|
||||||
|
to_ast_node!(&'r HorizontalRule<'s>, AstNode::HorizontalRule);
|
||||||
|
to_ast_node!(&'r Keyword<'s>, AstNode::Keyword);
|
||||||
|
to_ast_node!(&'r BabelCall<'s>, AstNode::BabelCall);
|
||||||
|
to_ast_node!(&'r LatexEnvironment<'s>, AstNode::LatexEnvironment);
|
||||||
|
to_ast_node!(&'r Bold<'s>, AstNode::Bold);
|
||||||
|
to_ast_node!(&'r Italic<'s>, AstNode::Italic);
|
||||||
|
to_ast_node!(&'r Underline<'s>, AstNode::Underline);
|
||||||
|
to_ast_node!(&'r StrikeThrough<'s>, AstNode::StrikeThrough);
|
||||||
|
to_ast_node!(&'r Code<'s>, AstNode::Code);
|
||||||
|
to_ast_node!(&'r Verbatim<'s>, AstNode::Verbatim);
|
||||||
|
to_ast_node!(&'r PlainText<'s>, AstNode::PlainText);
|
||||||
|
to_ast_node!(&'r RegularLink<'s>, AstNode::RegularLink);
|
||||||
|
to_ast_node!(&'r RadioLink<'s>, AstNode::RadioLink);
|
||||||
|
to_ast_node!(&'r RadioTarget<'s>, AstNode::RadioTarget);
|
||||||
|
to_ast_node!(&'r PlainLink<'s>, AstNode::PlainLink);
|
||||||
|
to_ast_node!(&'r AngleLink<'s>, AstNode::AngleLink);
|
||||||
|
to_ast_node!(&'r OrgMacro<'s>, AstNode::OrgMacro);
|
||||||
|
to_ast_node!(&'r Entity<'s>, AstNode::Entity);
|
||||||
|
to_ast_node!(&'r LatexFragment<'s>, AstNode::LatexFragment);
|
||||||
|
to_ast_node!(&'r ExportSnippet<'s>, AstNode::ExportSnippet);
|
||||||
|
to_ast_node!(&'r FootnoteReference<'s>, AstNode::FootnoteReference);
|
||||||
|
to_ast_node!(&'r Citation<'s>, AstNode::Citation);
|
||||||
|
to_ast_node!(&'r CitationReference<'s>, AstNode::CitationReference);
|
||||||
|
to_ast_node!(&'r InlineBabelCall<'s>, AstNode::InlineBabelCall);
|
||||||
|
to_ast_node!(&'r InlineSourceBlock<'s>, AstNode::InlineSourceBlock);
|
||||||
|
to_ast_node!(&'r LineBreak<'s>, AstNode::LineBreak);
|
||||||
|
to_ast_node!(&'r Target<'s>, AstNode::Target);
|
||||||
|
to_ast_node!(&'r StatisticsCookie<'s>, AstNode::StatisticsCookie);
|
||||||
|
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);
|
332
src/iter/ast_node_iter.rs
Normal file
332
src/iter/ast_node_iter.rs
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
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::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::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;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/// Iterator over the AST nodes contained within the starting node.
|
||||||
|
///
|
||||||
|
/// This only iterates over the children, not the starting node itself. So an AstNodeIter::PlainList would only return PlainListItems, not the PlainList.
|
||||||
|
///
|
||||||
|
/// This only iterates over AST nodes, so an AstNodeIter::Heading would iterate over both the title and section contents, but it would not iterate over simple strings like the TODO keyword or priority.
|
||||||
|
pub(crate) enum AstNodeIter<'r, 's> {
|
||||||
|
// Document Nodes
|
||||||
|
Document(DocumentIter<'r, 's>),
|
||||||
|
Heading(HeadingIter<'r, 's>),
|
||||||
|
Section(SectionIter<'r, 's>),
|
||||||
|
// Elements
|
||||||
|
Paragraph(ParagraphIter<'r, 's>),
|
||||||
|
PlainList(PlainListIter<'r, 's>),
|
||||||
|
PlainListItem(PlainListItemIter<'r, 's>),
|
||||||
|
GreaterBlock(GreaterBlockIter<'r, 's>),
|
||||||
|
DynamicBlock(DynamicBlockIter<'r, 's>),
|
||||||
|
FootnoteDefinition(FootnoteDefinitionIter<'r, 's>),
|
||||||
|
Comment(CommentIter<'r, 's>),
|
||||||
|
Drawer(DrawerIter<'r, 's>),
|
||||||
|
PropertyDrawer(PropertyDrawerIter<'r, 's>),
|
||||||
|
NodeProperty(NodePropertyIter<'r, 's>),
|
||||||
|
Table(TableIter<'r, 's>),
|
||||||
|
TableRow(TableRowIter<'r, 's>),
|
||||||
|
VerseBlock(VerseBlockIter<'r, 's>),
|
||||||
|
CommentBlock(CommentBlockIter<'r, 's>),
|
||||||
|
ExampleBlock(ExampleBlockIter<'r, 's>),
|
||||||
|
ExportBlock(ExportBlockIter<'r, 's>),
|
||||||
|
SrcBlock(SrcBlockIter<'r, 's>),
|
||||||
|
Clock(ClockIter<'r, 's>),
|
||||||
|
DiarySexp(DiarySexpIter<'r, 's>),
|
||||||
|
Planning(PlanningIter<'r, 's>),
|
||||||
|
FixedWidthArea(FixedWidthAreaIter<'r, 's>),
|
||||||
|
HorizontalRule(HorizontalRuleIter<'r, 's>),
|
||||||
|
Keyword(KeywordIter<'r, 's>),
|
||||||
|
BabelCall(BabelCallIter<'r, 's>),
|
||||||
|
LatexEnvironment(LatexEnvironmentIter<'r, 's>),
|
||||||
|
// Objects
|
||||||
|
Bold(BoldIter<'r, 's>),
|
||||||
|
Italic(ItalicIter<'r, 's>),
|
||||||
|
Underline(UnderlineIter<'r, 's>),
|
||||||
|
StrikeThrough(StrikeThroughIter<'r, 's>),
|
||||||
|
Code(CodeIter<'r, 's>),
|
||||||
|
Verbatim(VerbatimIter<'r, 's>),
|
||||||
|
PlainText(PlainTextIter<'r, 's>),
|
||||||
|
RegularLink(RegularLinkIter<'r, 's>),
|
||||||
|
RadioLink(RadioLinkIter<'r, 's>),
|
||||||
|
RadioTarget(RadioTargetIter<'r, 's>),
|
||||||
|
PlainLink(PlainLinkIter<'r, 's>),
|
||||||
|
AngleLink(AngleLinkIter<'r, 's>),
|
||||||
|
OrgMacro(OrgMacroIter<'r, 's>),
|
||||||
|
Entity(EntityIter<'r, 's>),
|
||||||
|
LatexFragment(LatexFragmentIter<'r, 's>),
|
||||||
|
ExportSnippet(ExportSnippetIter<'r, 's>),
|
||||||
|
FootnoteReference(FootnoteReferenceIter<'r, 's>),
|
||||||
|
Citation(CitationIter<'r, 's>),
|
||||||
|
CitationReference(CitationReferenceIter<'r, 's>),
|
||||||
|
InlineBabelCall(InlineBabelCallIter<'r, 's>),
|
||||||
|
InlineSourceBlock(InlineSourceBlockIter<'r, 's>),
|
||||||
|
LineBreak(LineBreakIter<'r, 's>),
|
||||||
|
Target(TargetIter<'r, 's>),
|
||||||
|
StatisticsCookie(StatisticsCookieIter<'r, 's>),
|
||||||
|
Subscript(SubscriptIter<'r, 's>),
|
||||||
|
Superscript(SuperscriptIter<'r, 's>),
|
||||||
|
TableCell(TableCellIter<'r, 's>),
|
||||||
|
Timestamp(TimestampIter<'r, 's>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> AstNodeIter<'r, 's> {
|
||||||
|
pub(crate) fn from_ast_node(node: &AstNode<'r, 's>) -> AstNodeIter<'r, 's> {
|
||||||
|
match node {
|
||||||
|
AstNode::Document(inner) => AstNodeIter::Document(inner.into_iter()),
|
||||||
|
AstNode::Heading(inner) => AstNodeIter::Heading(inner.into_iter()),
|
||||||
|
AstNode::Section(inner) => AstNodeIter::Section(inner.into_iter()),
|
||||||
|
AstNode::Paragraph(inner) => AstNodeIter::Paragraph(inner.into_iter()),
|
||||||
|
AstNode::PlainList(inner) => AstNodeIter::PlainList(inner.into_iter()),
|
||||||
|
AstNode::PlainListItem(inner) => AstNodeIter::PlainListItem(inner.into_iter()),
|
||||||
|
AstNode::GreaterBlock(inner) => AstNodeIter::GreaterBlock(inner.into_iter()),
|
||||||
|
AstNode::DynamicBlock(inner) => AstNodeIter::DynamicBlock(inner.into_iter()),
|
||||||
|
AstNode::FootnoteDefinition(inner) => {
|
||||||
|
AstNodeIter::FootnoteDefinition(inner.into_iter())
|
||||||
|
}
|
||||||
|
AstNode::Comment(inner) => AstNodeIter::Comment(inner.into_iter()),
|
||||||
|
AstNode::Drawer(inner) => AstNodeIter::Drawer(inner.into_iter()),
|
||||||
|
AstNode::PropertyDrawer(inner) => AstNodeIter::PropertyDrawer(inner.into_iter()),
|
||||||
|
AstNode::NodeProperty(inner) => AstNodeIter::NodeProperty(inner.into_iter()),
|
||||||
|
AstNode::Table(inner) => AstNodeIter::Table(inner.into_iter()),
|
||||||
|
AstNode::TableRow(inner) => AstNodeIter::TableRow(inner.into_iter()),
|
||||||
|
AstNode::VerseBlock(inner) => AstNodeIter::VerseBlock(inner.into_iter()),
|
||||||
|
AstNode::CommentBlock(inner) => AstNodeIter::CommentBlock(inner.into_iter()),
|
||||||
|
AstNode::ExampleBlock(inner) => AstNodeIter::ExampleBlock(inner.into_iter()),
|
||||||
|
AstNode::ExportBlock(inner) => AstNodeIter::ExportBlock(inner.into_iter()),
|
||||||
|
AstNode::SrcBlock(inner) => AstNodeIter::SrcBlock(inner.into_iter()),
|
||||||
|
AstNode::Clock(inner) => AstNodeIter::Clock(inner.into_iter()),
|
||||||
|
AstNode::DiarySexp(inner) => AstNodeIter::DiarySexp(inner.into_iter()),
|
||||||
|
AstNode::Planning(inner) => AstNodeIter::Planning(inner.into_iter()),
|
||||||
|
AstNode::FixedWidthArea(inner) => AstNodeIter::FixedWidthArea(inner.into_iter()),
|
||||||
|
AstNode::HorizontalRule(inner) => AstNodeIter::HorizontalRule(inner.into_iter()),
|
||||||
|
AstNode::Keyword(inner) => AstNodeIter::Keyword(inner.into_iter()),
|
||||||
|
AstNode::BabelCall(inner) => AstNodeIter::BabelCall(inner.into_iter()),
|
||||||
|
AstNode::LatexEnvironment(inner) => AstNodeIter::LatexEnvironment(inner.into_iter()),
|
||||||
|
AstNode::Bold(inner) => AstNodeIter::Bold(inner.into_iter()),
|
||||||
|
AstNode::Italic(inner) => AstNodeIter::Italic(inner.into_iter()),
|
||||||
|
AstNode::Underline(inner) => AstNodeIter::Underline(inner.into_iter()),
|
||||||
|
AstNode::StrikeThrough(inner) => AstNodeIter::StrikeThrough(inner.into_iter()),
|
||||||
|
AstNode::Code(inner) => AstNodeIter::Code(inner.into_iter()),
|
||||||
|
AstNode::Verbatim(inner) => AstNodeIter::Verbatim(inner.into_iter()),
|
||||||
|
AstNode::PlainText(inner) => AstNodeIter::PlainText(inner.into_iter()),
|
||||||
|
AstNode::RegularLink(inner) => AstNodeIter::RegularLink(inner.into_iter()),
|
||||||
|
AstNode::RadioLink(inner) => AstNodeIter::RadioLink(inner.into_iter()),
|
||||||
|
AstNode::RadioTarget(inner) => AstNodeIter::RadioTarget(inner.into_iter()),
|
||||||
|
AstNode::PlainLink(inner) => AstNodeIter::PlainLink(inner.into_iter()),
|
||||||
|
AstNode::AngleLink(inner) => AstNodeIter::AngleLink(inner.into_iter()),
|
||||||
|
AstNode::OrgMacro(inner) => AstNodeIter::OrgMacro(inner.into_iter()),
|
||||||
|
AstNode::Entity(inner) => AstNodeIter::Entity(inner.into_iter()),
|
||||||
|
AstNode::LatexFragment(inner) => AstNodeIter::LatexFragment(inner.into_iter()),
|
||||||
|
AstNode::ExportSnippet(inner) => AstNodeIter::ExportSnippet(inner.into_iter()),
|
||||||
|
AstNode::FootnoteReference(inner) => AstNodeIter::FootnoteReference(inner.into_iter()),
|
||||||
|
AstNode::Citation(inner) => AstNodeIter::Citation(inner.into_iter()),
|
||||||
|
AstNode::CitationReference(inner) => AstNodeIter::CitationReference(inner.into_iter()),
|
||||||
|
AstNode::InlineBabelCall(inner) => AstNodeIter::InlineBabelCall(inner.into_iter()),
|
||||||
|
AstNode::InlineSourceBlock(inner) => AstNodeIter::InlineSourceBlock(inner.into_iter()),
|
||||||
|
AstNode::LineBreak(inner) => AstNodeIter::LineBreak(inner.into_iter()),
|
||||||
|
AstNode::Target(inner) => AstNodeIter::Target(inner.into_iter()),
|
||||||
|
AstNode::StatisticsCookie(inner) => AstNodeIter::StatisticsCookie(inner.into_iter()),
|
||||||
|
AstNode::Subscript(inner) => AstNodeIter::Subscript(inner.into_iter()),
|
||||||
|
AstNode::Superscript(inner) => AstNodeIter::Superscript(inner.into_iter()),
|
||||||
|
AstNode::TableCell(inner) => AstNodeIter::TableCell(inner.into_iter()),
|
||||||
|
AstNode::Timestamp(inner) => AstNodeIter::Timestamp(inner.into_iter()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
multi_field_iter!(
|
||||||
|
Document<'s>,
|
||||||
|
DocumentIter,
|
||||||
|
zeroth_section,
|
||||||
|
std::option::Iter<'r, Section<'s>>,
|
||||||
|
children,
|
||||||
|
std::slice::Iter<'r, Heading<'s>>
|
||||||
|
);
|
||||||
|
multi_field_iter!(
|
||||||
|
Heading<'s>,
|
||||||
|
HeadingIter,
|
||||||
|
title,
|
||||||
|
std::slice::Iter<'r, Object<'s>>,
|
||||||
|
children,
|
||||||
|
std::slice::Iter<'r, DocumentElement<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(Section<'s>, SectionIter, std::slice::Iter<'r, Element<'s>>);
|
||||||
|
children_iter!(
|
||||||
|
Paragraph<'s>,
|
||||||
|
ParagraphIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
PlainList<'s>,
|
||||||
|
PlainListIter,
|
||||||
|
std::slice::Iter<'r, PlainListItem<'s>>
|
||||||
|
);
|
||||||
|
multi_field_iter!(
|
||||||
|
PlainListItem<'s>,
|
||||||
|
PlainListItemIter,
|
||||||
|
tag,
|
||||||
|
std::slice::Iter<'r, Object<'s>>,
|
||||||
|
children,
|
||||||
|
std::slice::Iter<'r, Element<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
GreaterBlock<'s>,
|
||||||
|
GreaterBlockIter,
|
||||||
|
std::slice::Iter<'r, Element<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
DynamicBlock<'s>,
|
||||||
|
DynamicBlockIter,
|
||||||
|
std::slice::Iter<'r, Element<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
FootnoteDefinition<'s>,
|
||||||
|
FootnoteDefinitionIter,
|
||||||
|
std::slice::Iter<'r, Element<'s>>
|
||||||
|
);
|
||||||
|
empty_iter!(Comment<'s>, CommentIter);
|
||||||
|
children_iter!(Drawer<'s>, DrawerIter, std::slice::Iter<'r, Element<'s>>);
|
||||||
|
children_iter!(
|
||||||
|
PropertyDrawer<'s>,
|
||||||
|
PropertyDrawerIter,
|
||||||
|
std::slice::Iter<'r, NodeProperty<'s>>
|
||||||
|
);
|
||||||
|
empty_iter!(NodeProperty<'s>, NodePropertyIter);
|
||||||
|
children_iter!(Table<'s>, TableIter, std::slice::Iter<'r, TableRow<'s>>);
|
||||||
|
children_iter!(
|
||||||
|
TableRow<'s>,
|
||||||
|
TableRowIter,
|
||||||
|
std::slice::Iter<'r, TableCell<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
VerseBlock<'s>,
|
||||||
|
VerseBlockIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
empty_iter!(CommentBlock<'s>, CommentBlockIter);
|
||||||
|
empty_iter!(ExampleBlock<'s>, ExampleBlockIter);
|
||||||
|
empty_iter!(ExportBlock<'s>, ExportBlockIter);
|
||||||
|
empty_iter!(SrcBlock<'s>, SrcBlockIter);
|
||||||
|
empty_iter!(Clock<'s>, ClockIter);
|
||||||
|
empty_iter!(DiarySexp<'s>, DiarySexpIter);
|
||||||
|
empty_iter!(Planning<'s>, PlanningIter);
|
||||||
|
empty_iter!(FixedWidthArea<'s>, FixedWidthAreaIter);
|
||||||
|
empty_iter!(HorizontalRule<'s>, HorizontalRuleIter);
|
||||||
|
empty_iter!(Keyword<'s>, KeywordIter);
|
||||||
|
empty_iter!(BabelCall<'s>, BabelCallIter);
|
||||||
|
empty_iter!(LatexEnvironment<'s>, LatexEnvironmentIter);
|
||||||
|
children_iter!(Bold<'s>, BoldIter, std::slice::Iter<'r, Object<'s>>);
|
||||||
|
children_iter!(Italic<'s>, ItalicIter, std::slice::Iter<'r, Object<'s>>);
|
||||||
|
children_iter!(
|
||||||
|
Underline<'s>,
|
||||||
|
UnderlineIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
StrikeThrough<'s>,
|
||||||
|
StrikeThroughIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
empty_iter!(Code<'s>, CodeIter);
|
||||||
|
empty_iter!(Verbatim<'s>, VerbatimIter);
|
||||||
|
empty_iter!(PlainText<'s>, PlainTextIter);
|
||||||
|
empty_iter!(RegularLink<'s>, RegularLinkIter);
|
||||||
|
children_iter!(
|
||||||
|
RadioLink<'s>,
|
||||||
|
RadioLinkIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
children_iter!(
|
||||||
|
RadioTarget<'s>,
|
||||||
|
RadioTargetIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
empty_iter!(PlainLink<'s>, PlainLinkIter);
|
||||||
|
empty_iter!(AngleLink<'s>, AngleLinkIter);
|
||||||
|
empty_iter!(OrgMacro<'s>, OrgMacroIter);
|
||||||
|
empty_iter!(Entity<'s>, EntityIter);
|
||||||
|
empty_iter!(LatexFragment<'s>, LatexFragmentIter);
|
||||||
|
empty_iter!(ExportSnippet<'s>, ExportSnippetIter);
|
||||||
|
multi_field_iter!(
|
||||||
|
FootnoteReference<'s>,
|
||||||
|
FootnoteReferenceIter,
|
||||||
|
definition,
|
||||||
|
std::slice::Iter<'r, Object<'s>>,
|
||||||
|
);
|
||||||
|
empty_iter!(Citation<'s>, CitationIter);
|
||||||
|
empty_iter!(CitationReference<'s>, CitationReferenceIter);
|
||||||
|
empty_iter!(InlineBabelCall<'s>, InlineBabelCallIter);
|
||||||
|
empty_iter!(InlineSourceBlock<'s>, InlineSourceBlockIter);
|
||||||
|
empty_iter!(LineBreak<'s>, LineBreakIter);
|
||||||
|
empty_iter!(Target<'s>, TargetIter);
|
||||||
|
empty_iter!(StatisticsCookie<'s>, StatisticsCookieIter);
|
||||||
|
empty_iter!(Subscript<'s>, SubscriptIter);
|
||||||
|
empty_iter!(Superscript<'s>, SuperscriptIter);
|
||||||
|
children_iter!(
|
||||||
|
TableCell<'s>,
|
||||||
|
TableCellIter,
|
||||||
|
std::slice::Iter<'r, Object<'s>>
|
||||||
|
);
|
||||||
|
empty_iter!(Timestamp<'s>, TimestampIter);
|
114
src/iter/macros.rs
Normal file
114
src/iter/macros.rs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/// 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) => {
|
||||||
|
pub struct $itertype<'r, 's> {
|
||||||
|
next: $innertype,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> Iterator for $itertype<'r, 's> {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.next.next().map(Into::<AstNode>::into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
type IntoIter = $itertype<'r, 's>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
$itertype {
|
||||||
|
next: self.children.iter(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use children_iter;
|
||||||
|
|
||||||
|
/// Create iterators for ast nodes that do not contain any ast node children.
|
||||||
|
macro_rules! empty_iter {
|
||||||
|
($astnodetype:ty, $itertype:ident) => {
|
||||||
|
pub struct $itertype<'r, 's> {
|
||||||
|
phantom: PhantomData<&'r $astnodetype>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> Iterator for $itertype<'r, 's> {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
type IntoIter = $itertype<'r, 's>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
$itertype {
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use empty_iter;
|
||||||
|
|
||||||
|
/// Create iterators for ast nodes where it has to iterate over multiple child lists.
|
||||||
|
macro_rules! multi_field_iter {
|
||||||
|
($astnodetype:ty, $itertype:ident, $firstfieldname: ident, $firstinnertype:ty, $($fieldname: ident, $innertype:ty),*) => {
|
||||||
|
pub struct $itertype<'r, 's> {
|
||||||
|
$firstfieldname: $firstinnertype,
|
||||||
|
$(
|
||||||
|
$fieldname: $innertype,
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> Iterator for $itertype<'r, 's> {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.$firstfieldname.next().map(Into::<AstNode>::into)
|
||||||
|
$(
|
||||||
|
.or_else(|| self.$fieldname.next().map(Into::<AstNode>::into))
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r, 's> IntoIterator for &'r $astnodetype {
|
||||||
|
type Item = AstNode<'r, 's>;
|
||||||
|
|
||||||
|
type IntoIter = $itertype<'r, 's>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
$itertype {
|
||||||
|
$firstfieldname: self.$firstfieldname.iter(),
|
||||||
|
$(
|
||||||
|
$fieldname: self.$fieldname.iter(),
|
||||||
|
),*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use multi_field_iter;
|
5
src/iter/mod.rs
Normal file
5
src/iter/mod.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
mod all_ast_node_iter;
|
||||||
|
mod ast_node;
|
||||||
|
mod ast_node_iter;
|
||||||
|
mod macros;
|
||||||
|
pub(crate) use ast_node::AstNode;
|
@ -8,6 +8,7 @@ pub mod compare;
|
|||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
mod error;
|
mod error;
|
||||||
|
mod iter;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ use super::in_buffer_settings::apply_in_buffer_settings;
|
|||||||
use super::in_buffer_settings::scan_for_in_buffer_settings;
|
use super::in_buffer_settings::scan_for_in_buffer_settings;
|
||||||
use super::org_source::OrgSource;
|
use super::org_source::OrgSource;
|
||||||
use super::section::zeroth_section;
|
use super::section::zeroth_section;
|
||||||
use super::token::AllTokensIterator;
|
|
||||||
use super::token::Token;
|
|
||||||
use super::util::get_consumed;
|
use super::util::get_consumed;
|
||||||
use crate::context::parser_with_context;
|
use crate::context::parser_with_context;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
@ -19,6 +17,7 @@ use crate::context::RefContext;
|
|||||||
use crate::error::CustomError;
|
use crate::error::CustomError;
|
||||||
use crate::error::MyError;
|
use crate::error::MyError;
|
||||||
use crate::error::Res;
|
use crate::error::Res;
|
||||||
|
use crate::iter::AstNode;
|
||||||
use crate::parser::org_source::convert_error;
|
use crate::parser::org_source::convert_error;
|
||||||
use crate::parser::util::blank_line;
|
use crate::parser::util::blank_line;
|
||||||
use crate::types::Document;
|
use crate::types::Document;
|
||||||
@ -111,15 +110,14 @@ fn document_org_source<'b, 'g, 'r, 's>(
|
|||||||
_document(context, input).map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
_document(context, input).map(|(rem, out)| (Into::<&str>::into(rem), out))?;
|
||||||
{
|
{
|
||||||
// If there are radio targets in this document then we need to parse the entire document again with the knowledge of the radio targets.
|
// If there are radio targets in this document then we need to parse the entire document again with the knowledge of the radio targets.
|
||||||
let all_radio_targets: Vec<&Vec<Object<'_>>> = document
|
let all_radio_targets: Vec<&Vec<Object<'_>>> = Into::<AstNode>::into(&document)
|
||||||
.iter_tokens()
|
.into_iter()
|
||||||
.filter_map(|tkn| match tkn {
|
.filter_map(|ast_node| {
|
||||||
Token::Object(obj) => Some(obj),
|
if let AstNode::RadioTarget(ast_node) = ast_node {
|
||||||
_ => None,
|
Some(ast_node)
|
||||||
})
|
} else {
|
||||||
.filter_map(|obj| match obj {
|
None
|
||||||
Object::RadioTarget(rt) => Some(rt),
|
}
|
||||||
_ => None,
|
|
||||||
})
|
})
|
||||||
.map(|rt| &rt.children)
|
.map(|rt| &rt.children)
|
||||||
.collect();
|
.collect();
|
||||||
@ -155,9 +153,3 @@ fn _document<'b, 'g, 'r, 's>(
|
|||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Document<'s> {
|
|
||||||
fn iter_tokens<'r>(&'r self) -> impl Iterator<Item = Token<'r, 's>> {
|
|
||||||
AllTokensIterator::new(Token::Document(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -43,7 +43,6 @@ mod table;
|
|||||||
mod target;
|
mod target;
|
||||||
mod text_markup;
|
mod text_markup;
|
||||||
mod timestamp;
|
mod timestamp;
|
||||||
mod token;
|
|
||||||
mod util;
|
mod util;
|
||||||
pub use document::parse;
|
pub use document::parse;
|
||||||
pub use document::parse_with_settings;
|
pub use document::parse_with_settings;
|
||||||
|
@ -1,135 +0,0 @@
|
|||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
use crate::types::Document;
|
|
||||||
use crate::types::DocumentElement;
|
|
||||||
use crate::types::Element;
|
|
||||||
use crate::types::Heading;
|
|
||||||
use crate::types::NodeProperty;
|
|
||||||
use crate::types::Object;
|
|
||||||
use crate::types::PlainListItem;
|
|
||||||
use crate::types::Section;
|
|
||||||
use crate::types::TableCell;
|
|
||||||
use crate::types::TableRow;
|
|
||||||
|
|
||||||
pub(crate) enum Token<'r, 's> {
|
|
||||||
Document(&'r Document<'s>),
|
|
||||||
Heading(&'r Heading<'s>),
|
|
||||||
Section(&'r Section<'s>),
|
|
||||||
Object(&'r Object<'s>),
|
|
||||||
Element(&'r Element<'s>),
|
|
||||||
PlainListItem(&'r PlainListItem<'s>),
|
|
||||||
TableRow(&'r TableRow<'s>),
|
|
||||||
TableCell(&'r TableCell<'s>),
|
|
||||||
NodeProperty(&'r NodeProperty<'s>),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'r, 's> Token<'r, 's> {
|
|
||||||
fn iter_tokens(&self) -> Box<dyn Iterator<Item = Token<'r, 's>> + '_> {
|
|
||||||
match self {
|
|
||||||
Token::Document(document) => Box::new(
|
|
||||||
document
|
|
||||||
.zeroth_section
|
|
||||||
.iter()
|
|
||||||
.map(Token::Section)
|
|
||||||
.chain(document.children.iter().map(Token::Heading)),
|
|
||||||
),
|
|
||||||
Token::Heading(heading) => Box::new(heading.title.iter().map(Token::Object).chain(
|
|
||||||
heading.children.iter().map(|de| match de {
|
|
||||||
DocumentElement::Heading(ref obj) => Token::Heading(obj),
|
|
||||||
DocumentElement::Section(ref obj) => Token::Section(obj),
|
|
||||||
}),
|
|
||||||
)),
|
|
||||||
Token::Section(section) => Box::new(section.children.iter().map(Token::Element)),
|
|
||||||
Token::Object(obj) => match obj {
|
|
||||||
Object::Bold(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Object::Italic(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Object::Underline(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Object::StrikeThrough(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Object::Code(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::Verbatim(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::PlainText(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::RegularLink(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::RadioLink(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Object::RadioTarget(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Object::PlainLink(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::AngleLink(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::OrgMacro(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::Entity(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::LatexFragment(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::ExportSnippet(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::FootnoteReference(inner) => {
|
|
||||||
Box::new(inner.definition.iter().map(Token::Object))
|
|
||||||
}
|
|
||||||
Object::Citation(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
|
||||||
Object::CitationReference(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
|
||||||
Object::InlineBabelCall(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::InlineSourceBlock(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::LineBreak(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::Target(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::StatisticsCookie(_) => Box::new(std::iter::empty()),
|
|
||||||
Object::Subscript(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
|
||||||
Object::Superscript(_) => Box::new(std::iter::empty()), // TODO: Iterate over children
|
|
||||||
Object::Timestamp(_) => Box::new(std::iter::empty()),
|
|
||||||
},
|
|
||||||
Token::Element(elem) => match elem {
|
|
||||||
Element::Paragraph(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Element::PlainList(inner) => {
|
|
||||||
Box::new(inner.children.iter().map(Token::PlainListItem))
|
|
||||||
}
|
|
||||||
Element::GreaterBlock(inner) => Box::new(inner.children.iter().map(Token::Element)),
|
|
||||||
Element::DynamicBlock(inner) => Box::new(inner.children.iter().map(Token::Element)),
|
|
||||||
Element::FootnoteDefinition(inner) => {
|
|
||||||
Box::new(inner.children.iter().map(Token::Element))
|
|
||||||
}
|
|
||||||
Element::Comment(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::Drawer(inner) => Box::new(inner.children.iter().map(Token::Element)),
|
|
||||||
Element::PropertyDrawer(inner) => {
|
|
||||||
Box::new(inner.children.iter().map(Token::NodeProperty))
|
|
||||||
}
|
|
||||||
Element::Table(inner) => Box::new(inner.children.iter().map(Token::TableRow)),
|
|
||||||
Element::VerseBlock(inner) => Box::new(inner.children.iter().map(Token::Object)),
|
|
||||||
Element::CommentBlock(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::ExampleBlock(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::ExportBlock(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::SrcBlock(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::Clock(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::DiarySexp(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::Planning(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::FixedWidthArea(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::HorizontalRule(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::Keyword(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::BabelCall(_) => Box::new(std::iter::empty()),
|
|
||||||
Element::LatexEnvironment(_) => Box::new(std::iter::empty()),
|
|
||||||
},
|
|
||||||
Token::PlainListItem(elem) => Box::new(elem.children.iter().map(Token::Element)),
|
|
||||||
Token::TableRow(elem) => Box::new(elem.children.iter().map(Token::TableCell)),
|
|
||||||
Token::TableCell(elem) => Box::new(elem.children.iter().map(Token::Object)),
|
|
||||||
Token::NodeProperty(_) => Box::new(std::iter::empty()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) struct AllTokensIterator<'r, 's> {
|
|
||||||
queued_tokens: VecDeque<Token<'r, 's>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'r, 's> AllTokensIterator<'r, 's> {
|
|
||||||
pub(crate) fn new(tkn: Token<'r, 's>) -> Self {
|
|
||||||
let mut queued_tokens = VecDeque::new();
|
|
||||||
queued_tokens.push_back(tkn);
|
|
||||||
AllTokensIterator { queued_tokens }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'r, 's> Iterator for AllTokensIterator<'r, 's> {
|
|
||||||
type Item = Token<'r, 's>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let next_token = match self.queued_tokens.pop_front() {
|
|
||||||
Some(tkn) => tkn,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
self.queued_tokens.extend(next_token.iter_tokens());
|
|
||||||
Some(next_token)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user