use alloc::vec::Vec;
use core::num::NonZeroUsize;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NonEmpty<T> {
head: T,
tail: Vec<T>,
}
impl<T> NonEmpty<T> {
#[must_use]
pub const fn new(head: T) -> Self {
Self { head, tail: Vec::new() }
}
pub fn push(&mut self, value: T) {
self.tail.push(value);
}
#[must_use]
pub const fn first(&self) -> &T {
&self.head
}
#[must_use]
pub fn len(&self) -> NonZeroUsize {
NonZeroUsize::MIN.saturating_add(self.tail.len())
}
pub fn iter(&self) -> impl Iterator<Item = &T> {
core::iter::once(&self.head).chain(self.tail.iter())
}
#[must_use]
pub fn filter<F>(self, mut predicate: F) -> Option<Self>
where
F: FnMut(&T) -> bool,
{
let mut kept = core::iter::once(self.head)
.chain(self.tail)
.filter(|value| predicate(value));
let head = kept.next()?;
let tail = kept.collect();
Some(Self { head, tail })
}
}
impl<T> IntoIterator for NonEmpty<T> {
type Item = T;
type IntoIter = core::iter::Chain<core::iter::Once<T>, alloc::vec::IntoIter<T>>;
fn into_iter(self) -> Self::IntoIter {
core::iter::once(self.head).chain(self.tail)
}
}
impl<'a, T> IntoIterator for &'a NonEmpty<T> {
type Item = &'a T;
type IntoIter = core::iter::Chain<core::iter::Once<&'a T>, core::slice::Iter<'a, T>>;
fn into_iter(self) -> Self::IntoIter {
core::iter::once(&self.head).chain(self.tail.iter())
}
}