//! A one-or-more iterator type use std::{ iter::{self, Once,FromIterator,Extend}, }; pub enum IntoIter { Many(std::vec::IntoIter), Single(Once), } /// A type that might hold once or more values pub enum MaybeSingle { Single(Option), Many(Vec), } impl Extend for MaybeSingle { fn extend>(&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 MaybeSingle { 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 FromIterator for MaybeSingle { fn from_iter>(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 ExactSizeIterator for IntoIter{} impl From> for MaybeSingle { fn from(from: Vec) -> Self { Self::Many(from) } } impl IntoIterator for MaybeSingle { type Item = T; type IntoIter = IntoIter; 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 Iterator for IntoIter { type Item = T; fn next(&mut self) -> Option { match self { Self::Many(ref mut many) => many.next(), Self::Single(ref mut once) => once.next(), } } fn size_hint(&self) -> (usize, Option) { match self { Self::Many(many) => many.size_hint(), Self::Single(_) => (0, Some(1)), } } }