Since once and chain return different types (both functions return the identically-named iterator adaptor), you can't return either an Once or a Chain from a function.
In these cases, I usually try to come up with some internal cleverness so that the types do end up being the same, e.g.:
use std::iter::{ once, Once, Chain };
impl IntoIterator for Example {
type Item = u8;
type IntoIter = Chain<Once<u8>, std::option::IntoIter<u8>>;
fn into_iter(self) -> Self::IntoIter {
match self {
Example::One => once(1u8).chain(None),
Example::Two(param) => once(2u8).chain(Some(param)),
}
}
}
If not, there's always the possibility to go full trait object and box the iterators if you really want to avoid writing a custom iterator type. However, creating a custom iterator type is the most "correct" solution in these kinds of situations.