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