#![no_std]
#![deny(unsafe_code, missing_docs)]
#![doc = include_str!("../README.md")]
#[cfg(test)]
mod tests;
use core::iter::FusedIterator;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct HeadTailIter<'a, T> {
tail: &'a [T],
}
impl<'a, T> Iterator for HeadTailIter<'a, T> {
type Item = (&'a T, &'a [T]);
fn next(&mut self) -> Option<Self::Item> {
let (head, tail) = self.tail.split_first()?;
self.tail = tail;
Some((head, tail))
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.len();
(n, Some(n))
}
fn count(self) -> usize {
self.len()
}
fn last(self) -> Option<Self::Item> {
self.tail.last().map(|t| (t, &[] as &[T]))
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if n > self.tail.len() {
self.tail = &[];
None
} else {
self.tail = &self.tail[n..];
self.next()
}
}
}
impl<T> FusedIterator for HeadTailIter<'_, T> {}
impl<T> ExactSizeIterator for HeadTailIter<'_, T> {
fn len(&self) -> usize {
self.tail.len()
}
}
pub trait HeadTailIterator {
type Item;
#[must_use]
fn head_tail_pairs(&self) -> HeadTailIter<'_, Self::Item>;
}
impl<T> HeadTailIterator for [T] {
type Item = T;
#[inline]
fn head_tail_pairs(&self) -> HeadTailIter<'_, Self::Item> {
HeadTailIter { tail: self }
}
}
impl<'a, T> From<&'a T> for HeadTailIter<'a, <T as HeadTailIterator>::Item>
where
T: HeadTailIterator + ?Sized,
{
#[inline]
fn from(value: &'a T) -> Self {
value.head_tail_pairs()
}
}