parent
0d3d847b09
commit
fbe6fa399a
@ -0,0 +1,120 @@
|
||||
//! A one-or-more iterator type
|
||||
|
||||
use std::{
|
||||
iter::{self, Once,FromIterator,Extend},
|
||||
};
|
||||
|
||||
pub enum IntoIter<T>
|
||||
{
|
||||
Many(std::vec::IntoIter<T>),
|
||||
Single(Once<T>),
|
||||
}
|
||||
|
||||
/// A type that might hold once or more values
|
||||
pub enum MaybeSingle<T> {
|
||||
Single(Option<T>),
|
||||
Many(Vec<T>),
|
||||
}
|
||||
|
||||
impl<T> Extend<T> for MaybeSingle<T>
|
||||
{
|
||||
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
|
||||
{
|
||||
match self {
|
||||
Self::Single(single) => {
|
||||
*self = Self::Many(iter::once(single.take().unwrap()).chain(iter).collect());
|
||||
},
|
||||
Self::Many(ref mut many) => {
|
||||
many.extend(iter);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> MaybeSingle<T> {
|
||||
pub fn is_single(&self) -> bool
|
||||
{
|
||||
if let Self::Single(_) = &self {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push(&mut self, value: T)
|
||||
{
|
||||
match self {
|
||||
Self::Single(single) => {
|
||||
let first = single.take().unwrap();
|
||||
*self = Self::Many(vec![first, value]);
|
||||
},
|
||||
Self::Many(ref mut many) => {
|
||||
many.push(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn single(from: T) -> Self
|
||||
{
|
||||
Self::Single(Some(from))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FromIterator<T> for MaybeSingle<T>
|
||||
{
|
||||
fn from_iter<I: IntoIterator<Item=T>>(iter: I) -> Self
|
||||
{
|
||||
let iter = iter.into_iter();
|
||||
let mut vec = match iter.size_hint() {
|
||||
(0, None) => Vec::new(),
|
||||
(_, Some(value)) | (value, None) => Vec::with_capacity(value),
|
||||
};
|
||||
vec.extend(iter);
|
||||
Self::Many(vec)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ExactSizeIterator for IntoIter<T>{}
|
||||
|
||||
impl<T> From<Vec<T>> for MaybeSingle<T>
|
||||
{
|
||||
fn from(from: Vec<T>) -> Self
|
||||
{
|
||||
Self::Many(from)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for MaybeSingle<T>
|
||||
{
|
||||
type Item = T;
|
||||
type IntoIter = IntoIter<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter
|
||||
{
|
||||
match self {
|
||||
Self::Single(Some(single)) => IntoIter::Single(iter::once(single)),
|
||||
Self::Many(many) => IntoIter::Many(many.into_iter()),
|
||||
_ => panic!("Invalid state"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Iterator for IntoIter<T>
|
||||
{
|
||||
type Item = T;
|
||||
fn next(&mut self) -> Option<Self::Item>
|
||||
{
|
||||
match self {
|
||||
Self::Many(ref mut many) => many.next(),
|
||||
Self::Single(ref mut once) => once.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>)
|
||||
{
|
||||
match self {
|
||||
Self::Many(many) => many.size_hint(),
|
||||
Self::Single(single) => (0, Some(1)),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue