You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
71 lines
1.6 KiB
71 lines
1.6 KiB
use std::iter::FusedIterator;
|
|
|
|
/// An iterator that may be empty.
|
|
#[derive(Debug, Clone)]
|
|
pub struct MaybeIter<I, T>(Option<I>)
|
|
where I: Iterator<Item=T>;
|
|
|
|
pub trait OptionIterExt<I, T>: Sized
|
|
where I: Iterator<Item=T>
|
|
{
|
|
/// Map this `Option<Iterator>` into an iterator that will yield the items of the iterator if it is present.
|
|
fn map_into_iter(self) -> MaybeIter<I, T>;
|
|
}
|
|
|
|
impl<E, T, I, Into: IntoIterator<IntoIter=I, Item=T>> OptionIterExt<I, T> for Result<Into, E>
|
|
where I: Iterator<Item = T>
|
|
{
|
|
#[inline] fn map_into_iter(self) -> MaybeIter<I, T> {
|
|
MaybeIter(self.ok().map(|x| x.into_iter()))
|
|
}
|
|
}
|
|
impl<T, I, Into: IntoIterator<IntoIter=I, Item=T>> OptionIterExt<I, T> for Option<Into>
|
|
where I: Iterator<Item = T>
|
|
{
|
|
#[inline] fn map_into_iter(self) -> MaybeIter<I, T> {
|
|
MaybeIter(self.map(|x| x.into_iter()))
|
|
}
|
|
}
|
|
|
|
impl<I, T> Iterator for MaybeIter<I, T>
|
|
where I: Iterator<Item=T>
|
|
{
|
|
type Item = T;
|
|
fn next(&mut self) -> Option<Self::Item>
|
|
{
|
|
if let Some(ref mut iter) = self.0
|
|
{
|
|
iter.next()
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
match &self.0 {
|
|
Some(i) => i.size_hint(),
|
|
None => (0, Some(0)),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<I, T> FusedIterator for MaybeIter<I, T>
|
|
where I: Iterator<Item=T> + FusedIterator{}
|
|
|
|
impl<I, T> ExactSizeIterator for MaybeIter<I, T>
|
|
where I: Iterator<Item=T> + ExactSizeIterator{}
|
|
|
|
impl<I, T> DoubleEndedIterator for MaybeIter<I, T>
|
|
where I: Iterator<Item=T> + DoubleEndedIterator
|
|
{
|
|
fn next_back(&mut self) -> Option<Self::Item> {
|
|
if let Some(ref mut iter) = self.0
|
|
{
|
|
iter.next_back()
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|
|
|
|
|