use std::iter::FusedIterator; /// An iterator that may be empty. #[derive(Debug, Clone)] pub struct MaybeIter(Option) where I: Iterator; pub trait OptionIterExt: Sized where I: Iterator { /// Map this `Option` into an iterator that will yield the items of the iterator if it is present. fn map_into_iter(self) -> MaybeIter; } impl> OptionIterExt for Result where I: Iterator { #[inline] fn map_into_iter(self) -> MaybeIter { MaybeIter(self.ok().map(|x| x.into_iter())) } } impl> OptionIterExt for Option where I: Iterator { #[inline] fn map_into_iter(self) -> MaybeIter { MaybeIter(self.map(|x| x.into_iter())) } } impl Iterator for MaybeIter where I: Iterator { type Item = T; fn next(&mut self) -> Option { if let Some(ref mut iter) = self.0 { iter.next() } else { None } } fn size_hint(&self) -> (usize, Option) { match &self.0 { Some(i) => i.size_hint(), None => (0, Some(0)), } } } impl FusedIterator for MaybeIter where I: Iterator + FusedIterator{} impl ExactSizeIterator for MaybeIter where I: Iterator + ExactSizeIterator{} impl DoubleEndedIterator for MaybeIter where I: Iterator + DoubleEndedIterator { fn next_back(&mut self) -> Option { if let Some(ref mut iter) = self.0 { iter.next_back() } else { None } } }