anon_iter 0.1.0

Return different Iterator types from function returning `-> impl Iterator`
Documentation
  • Coverage
  • 100%
    89 out of 89 items documented1 out of 12 items with examples
  • Size
  • Source code size: 19.76 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 14.81 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • nik-rev

anon_iter

crates.io docs.rs license msrv github

anon_iter is a much lighter alternative to the auto_enums crate, being less general-purpose but solving the most common use-case of this pattern (impl Iterator), without relying on macros - leading to much faster compile times and simpler syntax.

It does this by providing generic wrapper types like [AnonIter2] to allow to return different types of iterators from a function that returns -> impl Iterator.

Usage

Add this to your Cargo.toml:

[dependencies]
anon_iter = "0.1"

Wrap each iterator in [AnonIter2] to return 2 different iterators from the same function:

use anon_iter::AnonIter2;

fn foo(x: i32) -> impl Iterator<Item = i32> {
    match x {
        0 => AnonIter2::I1(1..10),
        _ => AnonIter2::I2(vec![5, 10].into_iter()),
    }
}

The crate Either allows similar functionality, as it too implements Iterator when its type parameters are both Iterator.

But this breaks down when you want to return 3 or more Iterators because you now have to do extra nesting (e.g. Either::Left(Either::Right(Either::Left(my_iter)))). With anon_iter, it's just AnonIter8::I3(my_iter).

Additionally, anon_iter makes code more readable because it may not be instantly obvious that we are using Either for this purpose, but with AnonEnum the intent is apparent.

An even simpler approach

If you just want to do this once without depending on this crate, copy-paste this into your project:

/// Wraps 2 `impl Iterator` which may be of different types
///
/// Functions returning `-> impl Iterator` must have the same return type
/// from all branches, but this is overly restrictive.
///
/// We may want to return 2 or more different iterators from the same function,
/// and this type allows that by wrapping each unique iterator in a variant of
/// this enum.
enum AnonIter<T, I1: Iterator<Item = T>, I2: Iterator<Item = T>> {
    /// The first `impl Iterator`
    I1(I1),
    /// The second `impl Iterator`
    I2(I2),
}

impl<T, I1: Iterator<Item = T>, I2: Iterator<Item = T>> Iterator for AnonIter<T, I1, I2> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        match self {
            AnonIter::I1(i1) => i1.next(),
            AnonIter::I2(i2) => i2.next(),
        }
    }
}