Rust で入れ子のコンテナを平たくイテレートするイテレータ

こんにちは。
Rust のイテレータまわりでちょっと手こずったので、後日のためのメモです。

まずは次のコードを見てください:

fn main() {
    let vec = vec![vec![0], vec![1, 2], vec![3, 4, 5]];

    for sub_vec in vec.iter() {
        for x in sub_vec.iter() {
            println!("{}", x);
        }
    }
}

実行したい方はこちら:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9eb206547a1d0390ad22b5137bae4086

これを実行すると 0, 1, 2, 3, 4, 5 の順に表示されます。vec がちょうど入れ子のコンテナになっていて、二重ループで中身をひとつひとつ取り出している形です。
これを、以下のようなコードで実現することを考えます:

struct MyContainer(Vec<Vec<u32>>);

impl MyContainer {
    fn iter(&self) -> ??? {
        ???
    }
}

fn main() {
    let vec = vec![vec![0], vec![1, 2], vec![3, 4, 5]];
    let con = MyContainer(vec);
    
    for x in con.iter() {
        println!("{}", x);
    }
}

iter メソッドの返り値となる型を定義する必要があり、そこでは Iterator を実装している必要がある、という感じです。
私なりの答えはこうです↓

struct MyContainer(Vec<Vec<u32>>);

impl MyContainer {
    fn iter(&self) -> MyIter<'_> {
        MyIter::new(self)
    }
}

struct MyIter<'a> {
    con: &'a MyContainer,
    iter: Option<(std::slice::Iter<'a, Vec<u32>>, std::slice::Iter<'a, u32>)>,
}

impl<'a> MyIter<'a> {
    fn new(con: &'a MyContainer) -> Self {
        Self { con, iter: None }
    }
}

impl<'a> Iterator for MyIter<'a> {
    type Item = &'a u32;
    fn next(&mut self) -> Option<Self::Item> {
        let Some(iter) = &mut self.iter else {
            // self.iter を準備する
            let mut outer = self.con.0.iter();
            let Some(inner) = outer.next() else {
                return None; // 内側の Vec がひとつも入っていなかった場合: おしまい
            };
            self.iter = Some((outer, inner.iter()));
            return self.next(); // 仕切り直し
        };

        let outer = &mut iter.0;
        let inner = &mut iter.1;

        // inner から取り出す
        let Some(item) = inner.next() else {
            // なかった場合は, outer からとってきて inner に入れる
            let Some(new_inner) = outer.next() else {
                return None; // outer が品切れパターン: おしまい
            };
            iter.1 = new_inner.iter();
            return self.next(); // 仕切り直し
        };
        Some(item)
    }
}

fn main() {
    let vec = vec![vec![0], vec![1, 2], vec![3, 4, 5]];
    let con = MyContainer(vec);

    for x in con.iter() {
        println!("{}", x);
    }
}

実行したい方はこちら:
play.rust-lang.org

中間状態を保存するために、外側のイテレータと内側のイテレータを補完するためのフィールドを準備しています。あえて Option にすることでコンストラクタを呼ぶタイミングではイテレータをセットせず、next のタイミングですっからかん判定ができるようになっています。これをしないと「あれっ??取り出せると思ってた内側のイテレータ準備できない・・・」ってなってつらくなります。
三重・四重の入れ子でも似たような実装で実現できると思うんですが、多少面倒くさいので、もっと楽な方法 (あるいは↑を書かなくてもさっと実現できるクレートとか) があれば教えてください。