use core::fmt;
use std::num::NonZeroUsize;
use crate::impl_nonempty_iter_for_arrays;
use crate::IntoNonEmptyIterator;
use crate::NonEmptyIterator;
pub trait NonEmptyArrayExt<T> {
fn as_nonempty_slice(&self) -> crate::NESlice<'_, T>;
fn nonzero_len(&self) -> NonZeroUsize;
fn into_nonempty_vec(self) -> crate::NEVec<T>;
}
#[derive(Clone)]
pub struct ArrayNonEmptyIterator<T, const C: usize> {
iter: core::array::IntoIter<T, C>,
}
impl<T, const C: usize> IntoIterator for ArrayNonEmptyIterator<T, C> {
type Item = T;
type IntoIter = core::array::IntoIter<T, C>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<T, const C: usize> NonEmptyIterator for ArrayNonEmptyIterator<T, C> {}
impl<T: fmt::Debug, const C: usize> fmt::Debug for ArrayNonEmptyIterator<T, C> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
impl_nonempty_iter_for_arrays!(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32
);
#[doc(hidden)]
#[macro_export]
macro_rules! impl_nonempty_iter_for_arrays {
($($i:literal),+ $(,)?) => {
$(
impl<T> IntoNonEmptyIterator for [T; $i] {
type IntoNEIter = ArrayNonEmptyIterator<T, $i>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
ArrayNonEmptyIterator {
iter: self.into_iter(),
}
}
}
impl<'a, T> IntoNonEmptyIterator for &'a [T; $i] {
type IntoNEIter = $crate::slice::Iter<'a,T>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
self.as_nonempty_slice().into_nonempty_iter()
}
}
impl<T> NonEmptyArrayExt<T> for [T; $i] {
fn as_nonempty_slice(&self) -> $crate::NESlice<'_, T> {
$crate::NESlice::try_from_slice(self).unwrap()
}
fn nonzero_len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked($i) }
}
fn into_nonempty_vec(self) -> $crate::NEVec<T> {
self.into_nonempty_iter().collect()
}
}
)+
};
}
#[cfg(test)]
mod test {
use crate::IntoNonEmptyIterator;
use crate::NonEmptyIterator;
#[test]
fn test_iter() {
let iter = [1, 2, 3, 4].into_nonempty_iter();
let (first, rest) = iter.next();
assert_eq!(1, first);
assert_eq!(vec![2, 3, 4], rest.into_iter().collect::<Vec<_>>());
let iter = [1].into_nonempty_iter();
let (first, rest) = iter.next();
assert_eq!(1, first);
assert_eq!(0, rest.into_iter().count());
assert_eq!(33, [1, -2, 33, 4].into_nonempty_iter().max());
}
#[test]
fn test_iter_ref() {
let iter = (&[1, 2, 3, 4]).into_nonempty_iter();
let (first, rest) = iter.next();
assert_eq!(&1, first);
assert_eq!(vec![&2, &3, &4], rest.into_iter().collect::<Vec<_>>());
let iter = (&[1]).into_nonempty_iter();
let (first, rest) = iter.next();
assert_eq!(&1, first);
assert_eq!(0, rest.into_iter().count());
assert_eq!(&33, (&[1, -2, 33, 4]).into_nonempty_iter().max());
}
}