macro_rules! generate_pattern_iterators {
{
// Forward iterator
forward:
$(#[$forward_iterator_attribute:meta])*
struct $forward_iterator:ident;
// Reverse iterator
reverse:
$(#[$reverse_iterator_attribute:meta])*
struct $reverse_iterator:ident;
// Stability of all generated items
stability:
$(#[$common_stability_attribute:meta])*
// Internal almost-iterator that is being delegated to
internal:
$internal_iterator:ident yielding ($iterty:ty);
// Kind of delegation - either single ended or double ended
delegate $($t:tt)*
} => { ... };
{
double ended; with $(#[$common_stability_attribute:meta])*,
$forward_iterator:ident,
$reverse_iterator:ident, $iterty:ty
} => { ... };
{
single ended; with $(#[$common_stability_attribute:meta])*,
$forward_iterator:ident,
$reverse_iterator:ident, $iterty:ty
} => { ... };
}
Expand description
This macro generates two public iterator structs
wrapping a private internal one that makes use of the Pattern
API.
For all patterns P: Pattern
the following items will be
generated (generics omitted):
struct $forward_iterator($internal_iterator); struct $reverse_iterator($internal_iterator);
impl Iterator for $forward_iterator { /* internal ends up calling Searcher::next_match() */ }
impl DoubleEndedIterator for $forward_iterator where P::Searcher: DoubleEndedSearcher { /* internal ends up calling Searcher::next_match_back() */ }
impl Iterator for $reverse_iterator where P::Searcher: ReverseSearcher { /* internal ends up calling Searcher::next_match_back() */ }
impl DoubleEndedIterator for $reverse_iterator where P::Searcher: DoubleEndedSearcher { /* internal ends up calling Searcher::next_match() */ }
The internal one is defined outside the macro, and has almost the same
semantic as a DoubleEndedIterator by delegating to pattern::Searcher
and
pattern::ReverseSearcher
for both forward and reverse iteration.
“Almost”, because a Searcher
and a ReverseSearcher
for a given
Pattern
might not return the same elements, so actually implementing
DoubleEndedIterator
for it would be incorrect.
(See the docs in str::pattern
for more details)
However, the internal struct still represents a single ended iterator from
either end, and depending on pattern is also a valid double ended iterator,
so the two wrapper structs implement Iterator
and DoubleEndedIterator
depending on the concrete pattern type, leading
to the complex impls seen above.