Common type of iterators

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);
    }
}

(playground)

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);
    }
}

(playground)

2 Likes