anon_iter

Crates.ioanon_iter
lib.rsanon_iter
version0.1.0
created_at2025-09-17 16:23:53.804891+00
updated_at2025-09-17 16:23:53.804891+00
descriptionReturn different Iterator types from function returning `-> impl Iterator`
homepage
repositoryhttps://github.com/nik-rev/anon-iter
max_upload_size
id1843563
size20,244
Nik Revenco (nik-rev)

documentation

README

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(),
        }
    }
}
Commit count: 10

cargo fmt