From 8784da5179e17c1d62052d01f0b180b1dcb72943 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Wed, 27 Sep 2023 19:30:21 -0400 Subject: [PATCH] Implement all ast node iteration. --- src/iter/all_ast_node_iter.rs | 102 ++++++++++++++++++++++++++++++++++ src/iter/ast_node_iter.rs | 65 ++++++++++++++++++++++ src/iter/mod.rs | 1 + 3 files changed, 168 insertions(+) create mode 100644 src/iter/all_ast_node_iter.rs diff --git a/src/iter/all_ast_node_iter.rs b/src/iter/all_ast_node_iter.rs new file mode 100644 index 0000000..1598990 --- /dev/null +++ b/src/iter/all_ast_node_iter.rs @@ -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>, + queue: VecDeque>, +} + +impl<'r, 's> Iterator for AllAstNodeIter<'r, 's> { + type Item = AstNode<'r, 's>; + + fn next(&mut self) -> Option { + 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(), + } + } +} diff --git a/src/iter/ast_node_iter.rs b/src/iter/ast_node_iter.rs index 4866681..39bac09 100644 --- a/src/iter/ast_node_iter.rs +++ b/src/iter/ast_node_iter.rs @@ -131,6 +131,71 @@ pub enum AstNodeIter<'r, 's> { Timestamp(TimestampIter<'r, 's>), } +impl<'r, 's> AstNodeIter<'r, 's> { + pub 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, diff --git a/src/iter/mod.rs b/src/iter/mod.rs index b622d37..c380ada 100644 --- a/src/iter/mod.rs +++ b/src/iter/mod.rs @@ -1,3 +1,4 @@ +mod all_ast_node_iter; mod ast_node; mod ast_node_iter; mod macros;