use crate::nev;
use crate::NEVec;
use crate::Singleton;
use std::borrow::Cow;
use std::cell::RefCell;
use std::cmp::Ordering;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::HashMap;
use std::collections::HashSet;
use std::hash::BuildHasher;
use std::hash::Hash;
use std::iter::Product;
use std::iter::Sum;
use std::num::NonZeroUsize;
use std::path::Path;
use std::path::PathBuf;
use std::rc::Rc;
use std::result::Result;
pub fn once<T>(value: T) -> Once<T> {
Once::new(value)
}
pub trait NonEmptyIterator: IntoIterator {
#[must_use]
fn next(self) -> (Self::Item, Self::IntoIter)
where
Self: Sized,
{
let mut iter = self.into_iter();
(iter.next().unwrap(), iter)
}
fn peekable(self) -> Peekable<Self::IntoIter>
where
Self: Sized,
{
let mut iter = self.into_iter();
Peekable {
first: iter.next().unwrap(),
rest: iter,
}
}
#[must_use]
fn all<F>(self, f: F) -> bool
where
Self: Sized,
F: FnMut(Self::Item) -> bool,
{
self.into_iter().all(f)
}
#[must_use]
fn any<F>(self, f: F) -> bool
where
Self: Sized,
F: FnMut(Self::Item) -> bool,
{
self.into_iter().any(f)
}
fn chain<U>(self, other: U) -> Chain<Self::IntoIter, U::IntoIter>
where
Self: Sized,
U: IntoIterator<Item = Self::Item>,
{
Chain {
inner: self.into_iter().chain(other),
}
}
fn cloned<'a, T>(self) -> Cloned<Self>
where
Self: Sized + NonEmptyIterator<Item = &'a T>,
T: Clone + 'a,
{
Cloned { iter: self }
}
#[must_use]
fn collect<B>(self) -> B
where
Self: Sized,
B: FromNonEmptyIterator<Self::Item>,
{
FromNonEmptyIterator::from_nonempty_iter(self)
}
fn copied<'a, T>(self) -> Copied<Self::IntoIter>
where
Self: Sized + NonEmptyIterator<Item = &'a T>,
T: Copy + 'a,
{
Copied {
iter: self.into_iter().copied(),
}
}
#[must_use]
fn count(self) -> NonZeroUsize
where
Self: Sized,
{
unsafe { NonZeroUsize::new_unchecked(self.into_iter().count()) }
}
fn enumerate(self) -> Enumerate<Self>
where
Self: Sized,
{
Enumerate { iter: self }
}
fn filter<P>(self, predicate: P) -> std::iter::Filter<<Self as IntoIterator>::IntoIter, P>
where
Self: Sized,
P: FnMut(&<Self as IntoIterator>::Item) -> bool,
{
self.into_iter().filter(predicate)
}
fn filter_map<B, F>(self, f: F) -> std::iter::FilterMap<<Self as IntoIterator>::IntoIter, F>
where
Self: Sized,
F: FnMut(<Self as IntoIterator>::Item) -> Option<B>,
{
self.into_iter().filter_map(f)
}
#[must_use]
fn find<P>(self, predicate: P) -> Option<Self::Item>
where
Self: Sized,
P: FnMut(&Self::Item) -> bool,
{
self.into_iter().find(predicate)
}
#[inline]
fn flat_map<U, F>(self, f: F) -> FlatMap<Self::IntoIter, U, F>
where
Self: Sized,
F: FnMut(Self::Item) -> U,
U: IntoNonEmptyIterator,
{
FlatMap {
inner: self.into_iter().flat_map(f),
}
}
#[must_use]
fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
self.into_iter().fold(init, f)
}
fn group_by<K, F>(self, f: F) -> NEGroupBy<Self, F>
where
Self: Sized,
F: FnMut(&Self::Item) -> K,
K: PartialEq,
{
NEGroupBy { iter: self, f }
}
fn intersperse(self, item: Self::Item) -> Intersperse<Self>
where
Self: Sized,
Self::Item: Clone,
{
Intersperse { iter: self, item }
}
#[inline]
fn map<U, F>(self, f: F) -> Map<Self, F>
where
Self: Sized,
F: FnMut(Self::Item) -> U,
{
Map {
iter: self.into_iter().map(f),
}
}
#[must_use]
fn max(self) -> Self::Item
where
Self: Sized,
Self::Item: Ord,
{
self.max_by(Ord::cmp)
}
#[must_use]
fn max_by<F>(self, compare: F) -> Self::Item
where
Self: Sized,
F: Fn(&Self::Item, &Self::Item) -> Ordering,
{
let (first, iter) = self.next();
iter.into_iter()
.fold(first, |acc, item| match compare(&acc, &item) {
Ordering::Less => item,
_ => acc,
})
}
#[must_use]
fn max_by_key<B, F>(self, mut key: F) -> Self::Item
where
Self: Sized,
B: Ord,
F: FnMut(&Self::Item) -> B,
{
self.map(|item| (key(&item), item))
.max_by(|(left_key, _), (right_key, _)| left_key.cmp(right_key))
.1
}
#[must_use]
fn min(self) -> Self::Item
where
Self: Sized,
Self::Item: Ord,
{
self.min_by(Ord::cmp)
}
#[must_use]
fn min_by<F>(self, compare: F) -> Self::Item
where
Self: Sized,
F: Fn(&Self::Item, &Self::Item) -> Ordering,
{
let (first, iter) = self.next();
iter.into_iter()
.fold(first, |acc, item| match compare(&acc, &item) {
Ordering::Greater => item,
_ => acc,
})
}
#[must_use]
fn min_by_key<B, F>(self, mut key: F) -> Self::Item
where
Self: Sized,
B: Ord,
F: FnMut(&Self::Item) -> B,
{
self.map(|item| (key(&item), item))
.min_by(|(left_key, _), (right_key, _)| left_key.cmp(right_key))
.1
}
fn sorted_by_key<K, F>(self, f: F) -> crate::vector::IntoIter<Self::Item>
where
Self: Sized,
K: Ord,
F: FnMut(&Self::Item) -> K,
{
let mut v = NEVec::from_nonempty_iter(self);
v.sort_by_key(f);
v.into_nonempty_iter()
}
fn nth(self, n: usize) -> Option<Self::Item>
where
Self: Sized,
{
self.into_iter().nth(n)
}
fn skip(self, n: usize) -> std::iter::Skip<<Self as IntoIterator>::IntoIter>
where
Self: Sized,
{
self.into_iter().skip(n)
}
fn skip_while<P>(self, pred: P) -> std::iter::SkipWhile<<Self as IntoIterator>::IntoIter, P>
where
Self: Sized,
P: FnMut(&<Self as IntoIterator>::Item) -> bool,
{
self.into_iter().skip_while(pred)
}
#[must_use]
fn sum<S>(self) -> S
where
Self: Sized + IntoIterator,
S: Sum<<Self as IntoIterator>::Item>,
{
Sum::sum(self.into_iter())
}
fn take(self, n: NonZeroUsize) -> Take<Self>
where
Self: Sized,
{
Take {
iter: self.into_iter().take(n.get()),
}
}
fn take_while<P>(self, pred: P) -> std::iter::TakeWhile<<Self as IntoIterator>::IntoIter, P>
where
Self: Sized,
P: FnMut(&<Self as IntoIterator>::Item) -> bool,
{
self.into_iter().take_while(pred)
}
#[must_use]
fn product<P>(self) -> P
where
Self: Sized + IntoIterator,
P: Product<<Self as IntoIterator>::Item>,
{
Product::product(self.into_iter())
}
fn zip<U>(self, other: U) -> Zip<Self::IntoIter, U::IntoIter>
where
Self: Sized,
U: IntoNonEmptyIterator,
{
Zip {
inner: self.into_iter().zip(other),
}
}
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where
FromA: Singleton<Item = A> + Extend<A>,
FromB: Singleton<Item = B> + Extend<B>,
Self: Sized + NonEmptyIterator<Item = (A, B)>,
{
let ((a, b), iter) = self.next();
let from_a = Singleton::singleton(a);
let from_b = Singleton::singleton(b);
let mut fused = (from_a, from_b);
fused.extend(iter);
fused
}
#[must_use]
fn reduce<F>(self, f: F) -> Self::Item
where
Self: Sized,
F: FnMut(Self::Item, Self::Item) -> Self::Item,
{
self.into_iter().reduce(f).unwrap()
}
}
pub trait FromNonEmptyIterator<T>: Sized {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = T>;
}
impl FromNonEmptyIterator<()> for () {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = ()>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl FromNonEmptyIterator<String> for String {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = String>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<'a> FromNonEmptyIterator<&'a str> for String {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = &'a str>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<'a> FromNonEmptyIterator<Cow<'a, str>> for String {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = Cow<'a, str>>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl FromNonEmptyIterator<char> for String {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = char>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<'a> FromNonEmptyIterator<&'a char> for String {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = &'a char>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<T> FromNonEmptyIterator<T> for Vec<T> {
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = T>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<K, V, S> FromNonEmptyIterator<(K, V)> for HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher + Default,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = (K, V)>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<T, S> FromNonEmptyIterator<T> for HashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher + Default,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = T>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<K, V> FromNonEmptyIterator<(K, V)> for BTreeMap<K, V>
where
K: Ord,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = (K, V)>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<T> FromNonEmptyIterator<T> for BTreeSet<T>
where
T: Ord,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = T>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<P> FromNonEmptyIterator<P> for PathBuf
where
P: AsRef<Path>,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = P>,
{
iter.into_nonempty_iter().into_iter().collect()
}
}
impl<A, E, V> FromNonEmptyIterator<Result<A, E>> for Result<V, E>
where
V: FromNonEmptyIterator<A>,
{
fn from_nonempty_iter<I>(iter: I) -> Result<V, E>
where
I: IntoNonEmptyIterator<Item = Result<A, E>>,
{
let (head, rest) = iter.into_nonempty_iter().next();
let head: A = head?;
let mut buf = NEVec::new(head);
for item in rest {
let item: A = item?;
buf.push(item);
}
let new_iter = buf.into_nonempty_iter();
let output: V = FromNonEmptyIterator::from_nonempty_iter(new_iter);
Ok(output)
}
}
pub trait IntoNonEmptyIterator: IntoIterator {
type IntoNEIter: NonEmptyIterator<Item = Self::Item>;
fn into_nonempty_iter(self) -> Self::IntoNEIter;
}
impl<I: NonEmptyIterator> IntoNonEmptyIterator for I {
type IntoNEIter = I;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
self
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Map<I: NonEmptyIterator, F> {
iter: std::iter::Map<I::IntoIter, F>,
}
impl<U, I, F> NonEmptyIterator for Map<I, F>
where
I: NonEmptyIterator,
F: FnMut(I::Item) -> U,
{
}
impl<U, I, F> IntoIterator for Map<I, F>
where
I: NonEmptyIterator,
F: FnMut(I::Item) -> U,
{
type Item = U;
type IntoIter = std::iter::Map<I::IntoIter, F>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<I, F> std::fmt::Debug for Map<I, F>
where
I: NonEmptyIterator,
I::IntoIter: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.iter.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Cloned<I> {
iter: I,
}
impl<'a, I, T: 'a> NonEmptyIterator for Cloned<I>
where
I: NonEmptyIterator<Item = &'a T>,
T: Clone,
{
}
impl<'a, I, T: 'a> IntoIterator for Cloned<I>
where
I: IntoIterator<Item = &'a T>,
T: Clone,
{
type Item = T;
type IntoIter = std::iter::Cloned<I::IntoIter>;
fn into_iter(self) -> Self::IntoIter {
self.iter.into_iter().cloned()
}
}
impl<I: std::fmt::Debug> std::fmt::Debug for Cloned<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.iter.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Enumerate<I> {
iter: I,
}
impl<I> NonEmptyIterator for Enumerate<I> where I: NonEmptyIterator {}
impl<I> IntoIterator for Enumerate<I>
where
I: IntoIterator,
{
type Item = (usize, I::Item);
type IntoIter = std::iter::Enumerate<I::IntoIter>;
fn into_iter(self) -> Self::IntoIter {
self.iter.into_iter().enumerate()
}
}
impl<I: std::fmt::Debug> std::fmt::Debug for Enumerate<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.iter.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Take<I: NonEmptyIterator> {
iter: std::iter::Take<I::IntoIter>,
}
impl<I> NonEmptyIterator for Take<I> where I: NonEmptyIterator {}
impl<I> IntoIterator for Take<I>
where
I: NonEmptyIterator,
{
type Item = I::Item;
type IntoIter = std::iter::Take<I::IntoIter>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<I> std::fmt::Debug for Take<I>
where
I: NonEmptyIterator,
I::IntoIter: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.iter.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Chain<A, B> {
inner: std::iter::Chain<A, B>,
}
impl<A, B> NonEmptyIterator for Chain<A, B>
where
A: Iterator,
B: Iterator<Item = A::Item>,
{
}
impl<A, B> IntoIterator for Chain<A, B>
where
A: Iterator,
B: Iterator<Item = A::Item>,
{
type Item = A::Item;
type IntoIter = std::iter::Chain<A, B>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<A, B> std::fmt::Debug for Chain<A, B>
where
A: std::fmt::Debug,
B: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Once<T> {
inner: std::iter::Once<T>,
}
impl<T> Once<T> {
pub(crate) fn new(value: T) -> Once<T> {
Once {
inner: std::iter::once(value),
}
}
}
impl<T> NonEmptyIterator for Once<T> {}
impl<T> IntoIterator for Once<T> {
type Item = T;
type IntoIter = std::iter::Once<T>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<T: std::fmt::Debug> std::fmt::Debug for Once<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Copied<I> {
iter: std::iter::Copied<I>,
}
impl<'a, I, T: 'a> NonEmptyIterator for Copied<I>
where
I: Iterator<Item = &'a T>,
T: Copy,
{
}
impl<'a, I, T: 'a> IntoIterator for Copied<I>
where
I: Iterator<Item = &'a T>,
T: Copy,
{
type Item = T;
type IntoIter = std::iter::Copied<I>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<'a, I, T: 'a> std::fmt::Debug for Copied<I>
where
I: Iterator<Item = &'a T> + std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.iter.fmt(f)
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Zip<A, B> {
inner: std::iter::Zip<A, B>,
}
impl<A, B> NonEmptyIterator for Zip<A, B>
where
A: Iterator,
B: Iterator,
{
}
impl<A, B> IntoIterator for Zip<A, B>
where
A: Iterator,
B: Iterator,
{
type Item = (A::Item, B::Item);
type IntoIter = std::iter::Zip<A, B>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<A, B> std::fmt::Debug for Zip<A, B>
where
A: std::fmt::Debug,
B: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
#[derive(Debug)]
pub struct NEGroupBy<I, F> {
iter: I,
f: F,
}
impl<I, K, F> NonEmptyIterator for NEGroupBy<I, F>
where
I: NonEmptyIterator,
F: FnMut(&I::Item) -> K,
K: PartialEq,
{
}
impl<I, K, F> IntoIterator for NEGroupBy<I, F>
where
I: IntoIterator,
F: FnMut(&I::Item) -> K,
K: PartialEq,
{
type Item = NEVec<I::Item>;
type IntoIter = GroupBy<<I as IntoIterator>::IntoIter, K, I::Item, F>;
fn into_iter(self) -> Self::IntoIter {
GroupBy {
iter: self.iter.into_iter(),
f: Rc::new(RefCell::new(self.f)),
prev: None,
curr: None,
}
}
}
#[derive(Debug)]
pub struct GroupBy<I, K, V, F> {
iter: I,
f: Rc<RefCell<F>>,
prev: Option<K>,
curr: Option<NEVec<V>>,
}
impl<I, K, V, F> Iterator for GroupBy<I, K, V, F>
where
I: Iterator<Item = V>,
F: FnMut(&I::Item) -> K,
K: PartialEq,
{
type Item = NEVec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.iter.next() {
None => return self.curr.take(),
Some(v) => {
let k = {
let mut f = self.f.borrow_mut();
f(&v)
};
match (self.prev.as_ref(), &mut self.curr) {
(Some(p), Some(c)) if p == &k => {
c.push(v);
}
(Some(_), Some(_)) => {
let curr = self.curr.take();
self.curr = Some(nev![v]);
self.prev = Some(k);
return curr;
}
(_, _) => {
self.prev = Some(k);
self.curr = Some(nev![v]);
}
}
}
}
}
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct FlatMap<I, U: IntoIterator, F> {
inner: std::iter::FlatMap<I, U, F>,
}
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> NonEmptyIterator for FlatMap<I, U, F> {}
impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> IntoIterator for FlatMap<I, U, F> {
type Item = U::Item;
type IntoIter = std::iter::FlatMap<I, U, F>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<I: std::fmt::Debug, U, F> std::fmt::Debug for FlatMap<I, U, F>
where
U: IntoIterator,
U::IntoIter: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
where
U: Clone + IntoIterator,
U::IntoIter: Clone,
{
fn clone(&self) -> Self {
FlatMap {
inner: self.inner.clone(),
}
}
}
#[derive(Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct NonEmptyIterAdapter<I> {
inner: I,
}
impl<I: Iterator> NonEmptyIterator for NonEmptyIterAdapter<I> {}
impl<I> IntoIterator for NonEmptyIterAdapter<I>
where
I: Iterator,
{
type Item = I::Item;
type IntoIter = I;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<I: std::fmt::Debug> std::fmt::Debug for NonEmptyIterAdapter<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
pub trait IntoIteratorExt {
type Item;
type IntoIter: NonEmptyIterator<Item = Self::Item>;
fn try_into_nonempty_iter(self) -> Option<Self::IntoIter>;
}
impl<T> IntoIteratorExt for T
where
T: IntoIterator,
{
type Item = T::Item;
type IntoIter = NonEmptyIterAdapter<std::iter::Peekable<T::IntoIter>>;
fn try_into_nonempty_iter(self) -> Option<Self::IntoIter> {
let mut iter = self.into_iter().peekable();
iter.peek()
.is_some()
.then_some(NonEmptyIterAdapter { inner: iter })
}
}
#[derive(Debug, Clone)]
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Peekable<I: Iterator> {
first: I::Item,
rest: I,
}
impl<I: Iterator> Peekable<I> {
pub const fn peek(&self) -> &I::Item {
&self.first
}
pub fn peek_mut(&mut self) -> &mut I::Item {
&mut self.first
}
}
impl<I: Iterator> NonEmptyIterator for Peekable<I> {}
impl<I: Iterator> IntoIterator for Peekable<I> {
type Item = I::Item;
type IntoIter = std::iter::Chain<std::iter::Once<I::Item>, I>;
fn into_iter(self) -> Self::IntoIter {
std::iter::once(self.first).chain(self.rest)
}
}
pub struct Intersperse<I>
where
I: NonEmptyIterator,
{
iter: I,
item: I::Item,
}
impl<I> NonEmptyIterator for Intersperse<I>
where
I: NonEmptyIterator,
I::Item: Clone,
{
}
impl<I> IntoIterator for Intersperse<I>
where
I: NonEmptyIterator,
I::Item: Clone,
{
type Item = I::Item;
type IntoIter = RawIntersperse<<I as IntoIterator>::IntoIter>;
fn into_iter(self) -> Self::IntoIter {
let mut iter = self.iter.into_iter();
let raw = RawIntersperse {
item: self.item.clone(),
next: iter.next(),
iter,
};
raw.into_iter()
}
}
pub struct RawIntersperse<I>
where
I: Iterator,
{
iter: I,
item: I::Item,
next: Option<I::Item>,
}
impl<I> Iterator for RawIntersperse<I>
where
I: Iterator,
I::Item: Clone,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
if self.next.is_none() {
match self.iter.next() {
Some(next) => {
self.next = Some(next);
Some(self.item.clone())
}
None => None,
}
} else {
self.next.take()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::nem;
use crate::NEMap;
#[test]
fn into_hashset() {
let m = nem!['a' => 1, 'b' => 2, 'c' => 3];
let _: HashSet<_> = m.values().collect();
}
#[test]
fn into_hashmap() {
let m = nem!['a' => 1, 'b' => 2, 'c' => 3];
let h: HashMap<_, _> = m.iter().map(|(k, v)| (*k, *v)).collect();
let n = NEMap::try_from(h).unwrap();
assert_eq!(m, n);
}
#[test]
fn peekable() {
let v = nev![0, 1, 2, 3];
let iter = v.into_nonempty_iter().peekable();
assert_eq!(&0, iter.peek());
let all = iter.collect::<NEVec<_>>();
assert_eq!(nev![0, 1, 2, 3], all);
let mut iter = all.into_nonempty_iter().peekable();
*iter.peek_mut() = 7;
let (first, rest) = iter.next();
assert_eq!(7, first);
assert_eq!(vec![1, 2, 3], rest.collect::<Vec<_>>());
let u = nev![0, 1, 2];
let p: NEVec<_> = u
.into_nonempty_iter()
.map(|n| n + 1)
.peekable()
.map(|n| n * 2)
.collect();
assert_eq!(nev![2, 4, 6], p);
}
}