You can combine/unify different iterator types using enums or trait objects. An enum that can help is Either
from the either
crate.
fn main() {
let bl = BusinessLogic {
data: vec![1, 2, 3],
};
let iterable = if true {
Left(bl.get_ids())
} else {
Right(iter::once(1))
};
for element in iterable {
println!("{}", element);
}
}
(playground)
The item type must still match, so I’ve replaced [1].iter()
with iter::once(1)
that has u32
items, not &u32
. You could also use <_>::into_iter([1])
or [1].iter().copied()
.
Trait objects, using the type dyn Iterator<Item = u32>
, need some form of indirection: Either by boxing the iterator
fn main() {
let bl = BusinessLogic {
data: vec![1, 2, 3],
};
let iterable: Box<dyn Iterator<Item = u32>> = if true {
Box::new(bl.get_ids())
} else {
Box::new(iter::once(1))
};
for element in iterable {
println!("{}", element);
}
}
or by placing in some dedicated local variables and creating a mutable reference
fn main() {
let bl = BusinessLogic {
data: vec![1, 2, 3],
};
let (mut iter1, mut iter2);
let iterable: &mut dyn Iterator<Item = u32> = if true {
iter1 = bl.get_ids();
&mut iter1
} else {
iter2 = iter::once(1);
&mut iter2
};
for element in iterable {
println!("{}", element);
}
}