diff --git a/src/iter/ast_node_iter.rs b/src/iter/ast_node_iter.rs index 851666e..1c4210d 100644 --- a/src/iter/ast_node_iter.rs +++ b/src/iter/ast_node_iter.rs @@ -202,35 +202,14 @@ impl<'r, 's> AstNodeIter<'r, 's> { } } -pub struct DocumentIter<'r, 's> { - zeroth_section: std::option::Iter<'r, Section<'s>>, - children: std::slice::Iter<'r, Heading<'s>>, -} -impl<'r, 's> Iterator for DocumentIter<'r, 's> { - type Item = AstNode<'r, 's>; - fn next(&mut self) -> Option { - self.zeroth_section - .next() - .map(Into::::into) - .or_else(|| self.children.next().map(Into::::into)) - } - - fn size_hint(&self) -> (usize, Option) { - let size = self.zeroth_section.len() + self.children.len(); - (size, Some(size)) - } -} -impl<'r, 's> ExactSizeIterator for DocumentIter<'r, 's> {} -impl<'r, 's> IntoIterator for &'r Document<'s> { - type Item = AstNode<'r, 's>; - type IntoIter = DocumentIter<'r, 's>; - fn into_iter(self) -> Self::IntoIter { - DocumentIter { - zeroth_section: self.zeroth_section.iter(), - children: self.children.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, diff --git a/src/iter/macros.rs b/src/iter/macros.rs index 18a265d..3f9333b 100644 --- a/src/iter/macros.rs +++ b/src/iter/macros.rs @@ -11,8 +11,15 @@ macro_rules! children_iter { fn next(&mut self) -> Option { self.next.next().map(Into::::into) } + + fn size_hint(&self) -> (usize, Option) { + let size = self.next.len(); + (size, Some(size)) + } } + impl<'r, 's> ExactSizeIterator for $itertype<'r, 's> {} + impl<'r, 's> IntoIterator for &'r $astnodetype { type Item = AstNode<'r, 's>; @@ -42,8 +49,14 @@ macro_rules! empty_iter { fn next(&mut self) -> Option { None } + + fn size_hint(&self) -> (usize, Option) { + (0, Some(0)) + } } + impl<'r, 's> ExactSizeIterator for $itertype<'r, 's> {} + impl<'r, 's> IntoIterator for &'r $astnodetype { type Item = AstNode<'r, 's>;