Crates.io | anon_iter |
lib.rs | anon_iter |
version | 0.1.0 |
created_at | 2025-09-17 16:23:53.804891+00 |
updated_at | 2025-09-17 16:23:53.804891+00 |
description | Return different Iterator types from function returning `-> impl Iterator` |
homepage | |
repository | https://github.com/nik-rev/anon-iter |
max_upload_size | |
id | 1843563 |
size | 20,244 |
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
.
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 Iterator
s 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.
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(),
}
}
}