This solution works for all iterators that implement DoubleEndedIterator:
Note that this solution is guaranteed to return all items, regardless of whether the iterator contains an even or odd number of them.
fn selfinterlace<Iter>(mut iter: Iter) -> impl Iterator<Item = Iter::Item>
where
    Iter: DoubleEndedIterator,
{
    let mut from_front = false;
    std::iter::from_fn(move || {
        from_front = !from_front;
        if from_front {
            iter.next()
        } else {
            iter.next_back()
        }
    })
}
fn main() {
    let range = (0..=8).into_iter();
    let iter = selfinterlace(range);
    println!("{:?}", iter.collect::<Vec<_>>());
}
[0, 8, 1, 7, 2, 6, 3, 5, 4]
The idea is that you store whether the next item should be from the front or the back, and then flip that in every iteration.
from_fn can take FnMut, meaning, it can take closures that store internal state. The internal state in this closure consists of the variables iter and from_front, which get moved into the closure through the move || keyword.