use std::{vec, mem, iter}; enum List { Node(Vec>), Leaf(T), } impl IntoIterator for List { type Item = List; type IntoIter = ListIter; fn into_iter(self) -> Self::IntoIter { match self { List::Node(vec) => ListIter::NodeIter(vec.into_iter()), leaf @ List::Leaf(_) => ListIter::LeafIter(iter::once(leaf)), } } } enum ListIter { NodeIter(vec::IntoIter>), LeafIter(iter::Once>), } impl ListIter { fn flatten(self) -> Flatten { Flatten { stack: Vec::new(), curr: self, } } } impl Iterator for ListIter { type Item = List; fn next(&mut self) -> Option { match *self { ListIter::NodeIter(ref mut v_iter) => v_iter.next(), ListIter::LeafIter(ref mut o_iter) => o_iter.next(), } } } struct Flatten { stack: Vec>, curr: ListIter, } // Flatten code is a little messy since we are shoehorning recursion into an Iterator impl Iterator for Flatten { type Item = T; fn next(&mut self) -> Option { loop { match self.curr.next() { Some(list) => { match list { node @ List::Node(_) => { self.stack.push(node.into_iter()); let len = self.stack.len(); mem::swap(&mut self.stack[len - 1], &mut self.curr); } List::Leaf(item) => return Some(item), } } None => { if let Some(next) = self.stack.pop() { self.curr = next; } else { return None; } } } } } } use List::*; fn main() { let list = Node(vec![Node(vec![Leaf(1)]), Leaf(2), Node(vec![Node(vec![Leaf(3), Leaf(4)]), Leaf(5)]), Node(vec![Node(vec![Node(vec![])])]), Node(vec![Node(vec![Node(vec![Leaf(6)])])]), Leaf(7), Leaf(8), Node(vec![])]); for elem in list.into_iter().flatten() { print!("{} ", elem); } println!(); }