#![cfg_attr(not(any(feature = "std", doc, test)), no_std)]
extern crate alloc;
use alloc::boxed::Box;
use alloc::collections::TryReserveError;
use alloc::vec;
use alloc::vec::{Drain, IntoIter, Vec};
use core::borrow::{Borrow, BorrowMut};
use core::convert::TryFrom;
use core::fmt::{Debug, Display, Formatter};
use core::iter::{Extend, FusedIterator};
use core::num::NonZeroUsize;
use core::ops::{Bound, Deref, DerefMut, Index, IndexMut, RangeBounds};
use core::slice::{Iter, IterMut, SliceIndex};
#[cfg(feature = "std")]
use std::io::{IoSlice, Write};
#[cfg(feature = "serde")]
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
macro_rules! unreachable_unchecked {
() => {{
#[cfg(debug_assertions)]
::core::unreachable!();
#[allow(unreachable_code)]
::core::hint::unreachable_unchecked()
}};
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
pub struct EmptyError;
impl Display for EmptyError {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "vector must be non-empty")
}
}
#[cfg(feature = "std")]
impl std::error::Error for EmptyError {}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NonEmpty<T>(Vec<T>);
impl<T> NonEmpty<T> {
#[inline]
pub fn new(v: T) -> Self {
Self(vec![v])
}
#[inline]
pub fn with_capacity(v: T, capacity: usize) -> Self {
let mut vec = Vec::with_capacity(capacity);
vec.push(v);
Self(vec)
}
#[inline]
pub const unsafe fn new_unchecked(vec: Vec<T>) -> Self {
Self(vec)
}
#[inline]
pub fn as_slice(&self) -> &[T] {
&self.0
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.0
}
#[inline]
pub fn as_ptr(&self) -> *const T {
self.0.as_ptr()
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.0.as_mut_ptr()
}
#[inline]
pub fn leak<'a>(self) -> &'a mut [T] {
self.0.leak()
}
#[inline]
pub fn into_boxed_slice(self) -> Box<[T]> {
self.0.into_boxed_slice()
}
#[inline]
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.0.len()) }
}
#[inline]
pub const fn is_empty(&self) -> bool {
false
}
#[inline]
pub fn capacity(&self) -> usize {
self.0.capacity()
}
#[inline]
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional)
}
#[inline]
pub fn reserve_exact(&mut self, additional: usize) {
self.0.reserve_exact(additional)
}
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.0.try_reserve(additional)
}
#[inline]
pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
self.0.try_reserve_exact(additional)
}
#[inline]
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit()
}
#[inline]
pub fn shrink_to(&mut self, min_capacity: usize) {
self.0.shrink_to(min_capacity)
}
#[inline]
pub fn first(&self) -> &T {
unsafe { self.0.get_unchecked(0) }
}
#[inline]
pub fn first_mut(&mut self) -> &mut T {
unsafe { self.0.get_unchecked_mut(0) }
}
#[inline]
pub fn last(&self) -> &T {
let i = self.len().get() - 1;
unsafe { self.0.get_unchecked(i) }
}
#[inline]
pub fn last_mut(&mut self) -> &mut T {
let i = self.len().get() - 1;
unsafe { self.0.get_unchecked_mut(i) }
}
#[inline]
pub fn split_first(&self) -> (&T, &[T]) {
(&self[0], &self[1..])
}
#[inline]
pub fn split_first_mut(&mut self) -> (&mut T, &mut [T]) {
let split = self.0.split_at_mut(1);
(&mut split.0[0], split.1)
}
#[inline]
pub fn split_last(&self) -> (&T, &[T]) {
let len = self.len().get();
(&self[len - 1], &self[..(len - 1)])
}
#[inline]
pub fn split_last_mut(&mut self) -> (&mut T, &mut [T]) {
let i = self.len().get() - 1;
let split = self.0.split_at_mut(i);
(&mut split.1[0], split.0)
}
#[inline]
pub fn truncate(&mut self, len: NonZeroUsize) {
self.0.truncate(len.get())
}
#[inline]
pub fn resize(&mut self, new_len: NonZeroUsize, value: T)
where
T: Clone,
{
self.0.resize(new_len.get(), value)
}
#[inline]
pub fn resize_with<F>(&mut self, new_len: NonZeroUsize, f: F)
where
F: FnMut() -> T,
{
self.0.resize_with(new_len.get(), f)
}
#[inline]
pub fn pop(&mut self) -> Option<T> {
if self.0.len() <= 1 {
None
} else {
self.0.pop()
}
}
#[inline]
pub fn push(&mut self, v: T) {
self.0.push(v)
}
#[inline]
pub fn insert(&mut self, index: usize, element: T) {
self.0.insert(index, element)
}
#[inline]
pub fn remove(&mut self, index: usize) -> Option<T> {
if index == 0 && self.0.len() == 1 {
None
} else {
Some(self.0.remove(index))
}
}
#[inline]
pub fn swap_remove(&mut self, index: usize) -> Option<T> {
if index == 0 && self.0.len() == 1 {
None
} else {
Some(self.0.swap_remove(index))
}
}
#[inline]
pub fn append(&mut self, other: &mut Vec<T>) {
self.0.append(other)
}
#[inline]
pub fn extend_from_slice(&mut self, other: &[T])
where
T: Clone,
{
self.0.extend_from_slice(other)
}
#[inline]
pub fn extend_from_within<R>(&mut self, src: R)
where
T: Clone,
R: RangeBounds<usize>,
{
self.0.extend_from_within(src)
}
#[inline]
pub fn dedup(&mut self)
where
T: PartialEq,
{
self.0.dedup()
}
#[inline]
pub fn dedup_by<F>(&mut self, same_bucket: F)
where
F: FnMut(&mut T, &mut T) -> bool,
{
self.0.dedup_by(same_bucket)
}
#[inline]
pub fn dedup_by_key<F, K>(&mut self, key: F)
where
F: FnMut(&mut T) -> K,
K: PartialEq,
{
self.0.dedup_by_key(key)
}
}
impl<T: Debug> Debug for NonEmpty<T> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl<T> From<(Vec<T>, T)> for NonEmpty<T> {
fn from((mut xs, x): (Vec<T>, T)) -> NonEmpty<T> {
xs.push(x);
NonEmpty(xs)
}
}
impl<T> From<(T, Vec<T>)> for NonEmpty<T> {
fn from((x, mut xs): (T, Vec<T>)) -> NonEmpty<T> {
xs.insert(0, x);
NonEmpty(xs)
}
}
impl<T> From<NonEmpty<T>> for Vec<T> {
fn from(v: NonEmpty<T>) -> Self {
v.0
}
}
impl<T: Default> Default for NonEmpty<T> {
fn default() -> Self {
ne_vec![T::default()]
}
}
impl<T> TryFrom<Vec<T>> for NonEmpty<T> {
type Error = EmptyError;
fn try_from(xs: Vec<T>) -> Result<Self, Self::Error> {
if xs.is_empty() {
Err(EmptyError)
} else {
Ok(NonEmpty(xs))
}
}
}
impl<T> From<Box<NonEmptySlice<T>>> for NonEmpty<T> {
#[inline]
fn from(slice: Box<NonEmptySlice<T>>) -> Self {
let v = Vec::from(slice.into_boxed_slice());
unsafe { Self::new_unchecked(v) }
}
}
impl<T> TryFrom<Box<[T]>> for NonEmpty<T> {
type Error = EmptyError;
#[inline]
fn try_from(value: Box<[T]>) -> Result<Self, Self::Error> {
let v = Vec::from(value);
Self::try_from(v)
}
}
impl<T> Deref for NonEmpty<T> {
type Target = NonEmptySlice<T>;
fn deref(&self) -> &Self::Target {
unsafe {
NonEmptySlice::unchecked(&self.0)
}
}
}
impl<T> DerefMut for NonEmpty<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
NonEmptySlice::unchecked_mut(&mut self.0)
}
}
}
impl<T> AsRef<[T]> for NonEmpty<T> {
#[inline]
fn as_ref(&self) -> &[T] {
self
}
}
impl<T> AsMut<[T]> for NonEmpty<T> {
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self.0.as_mut()
}
}
impl<T> AsRef<Vec<T>> for NonEmpty<T> {
#[inline]
fn as_ref(&self) -> &Vec<T> {
&self.0
}
}
impl<T> Borrow<[T]> for NonEmpty<T> {
#[inline]
fn borrow(&self) -> &[T] {
self.0.borrow()
}
}
impl<T> Borrow<Vec<T>> for NonEmpty<T> {
#[inline]
fn borrow(&self) -> &Vec<T> {
&self.0
}
}
impl<T> BorrowMut<[T]> for NonEmpty<T> {
#[inline]
fn borrow_mut(&mut self) -> &mut [T] {
self.0.borrow_mut()
}
}
impl<T, I: SliceIndex<[T]>> Index<I> for NonEmpty<T> {
type Output = I::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
self.0.index(index)
}
}
impl<T, I: SliceIndex<[T]>> IndexMut<I> for NonEmpty<T> {
#[inline]
fn index_mut(&mut self, index: I) -> &mut Self::Output {
self.0.index_mut(index)
}
}
impl<T> IntoIterator for NonEmpty<T> {
type Item = T;
type IntoIter = IntoIter<T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T> IntoIterator for &'a NonEmpty<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut NonEmpty<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<T> Extend<T> for NonEmpty<T> {
#[inline]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.0.extend(iter)
}
}
impl<'a, T: Copy + 'a> Extend<&'a T> for NonEmpty<T> {
#[inline]
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.0.extend(iter)
}
}
#[cfg(feature = "std")]
impl Write for NonEmpty<u8> {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.write(buf)
}
#[inline]
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> std::io::Result<usize> {
self.0.write_vectored(bufs)
}
#[inline]
fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
self.0.write_all(buf)
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
self.0.flush()
}
}
#[cfg(feature = "serde")]
impl<T: Serialize> Serialize for NonEmpty<T> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_slice().serialize(serializer)
}
}
#[cfg(feature = "serde")]
impl<'de, T: Deserialize<'de>> Deserialize<'de> for NonEmpty<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Self::try_from(<Vec<T>>::deserialize(deserializer)?)
.map_err(|_| D::Error::custom("vector must be non-empty"))
}
}
impl<T> NonEmpty<T> {
#[track_caller]
pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> Drain<T> {
let leftover_start = match range.start_bound() {
Bound::Included(&start) => start > 0,
Bound::Excluded(_) => true,
Bound::Unbounded => false,
};
if !leftover_start {
let leftover_end = match range.end_bound() {
Bound::Excluded(&end) => end < self.len().get(),
Bound::Included(&end) => end < self.len().get() - 1,
Bound::Unbounded => false,
};
if !leftover_end {
panic!(
"range specified for `NonEmpty::drain` must leave at least one element left"
);
}
}
self.0.drain(range)
}
#[inline]
pub fn drain_filter<F>(&mut self, f: F) -> DrainFilter<T, F>
where
F: FnMut(&mut T) -> bool,
{
DrainFilter::new(self, f)
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct DrainFilter<'a, T, F>
where
F: FnMut(&mut T) -> bool,
{
vec: &'a mut NonEmpty<T>,
f: F,
left: usize,
right: usize,
}
impl<'a, T, F> DrainFilter<'a, T, F>
where
F: FnMut(&mut T) -> bool,
{
#[inline]
pub fn new(vec: &'a mut NonEmpty<T>, f: F) -> Self {
let left = 0;
let right = vec.len().get();
Self {
vec,
f,
left,
right,
}
}
}
impl<'a, T, F> Iterator for DrainFilter<'a, T, F>
where
F: FnMut(&mut T) -> bool,
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
loop {
let any_yielded = self.left > 0 || self.right < self.vec.0.len();
if (any_yielded || self.right - self.left > 1) && self.left < self.right {
if (self.f)(&mut self.vec[self.left]) {
let item = self.vec.0.remove(self.left);
self.right -= 1;
break Some(item);
}
else {
self.left += 1;
}
}
else {
break None;
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let max = self.right - self.left;
(0, Some(max))
}
}
impl<'a, T, F> DoubleEndedIterator for DrainFilter<'a, T, F>
where
F: FnMut(&mut T) -> bool,
{
fn next_back(&mut self) -> Option<Self::Item> {
loop {
let any_yielded = self.right < self.vec.0.len() || self.left > 0;
if (any_yielded || self.right - self.left > 1) && self.right > self.left {
if (self.f)(&mut self.vec[self.right - 1]) {
let item = self.vec.0.remove(self.right - 1);
self.right -= 1;
break Some(item);
}
else {
self.right -= 1;
}
}
else {
break None;
}
}
}
}
impl<'a, T, F> FusedIterator for DrainFilter<'a, T, F> where F: FnMut(&mut T) -> bool {}
#[derive(Eq, Ord, Hash)]
#[repr(transparent)]
pub struct NonEmptySlice<T>([T]);
impl<T> NonEmptySlice<T> {
#[inline]
pub const unsafe fn unchecked(slice: &[T]) -> &Self {
debug_assert!(!slice.is_empty());
&*(slice as *const _ as *const Self)
}
#[inline]
pub unsafe fn unchecked_mut(slice: &mut [T]) -> &mut Self {
debug_assert!(!slice.is_empty());
&mut *(slice as *mut _ as *mut Self)
}
#[inline]
pub unsafe fn unchecked_boxed(slice: Box<[T]>) -> Box<Self> {
debug_assert!(!slice.is_empty());
let ptr = Box::into_raw(slice) as *mut Self;
Box::from_raw(ptr)
}
#[inline]
pub fn from_ref(val: &T) -> &Self {
let slice = core::slice::from_ref(val);
unsafe { Self::unchecked(slice) }
}
#[inline]
pub fn from_mut(val: &mut T) -> &mut Self {
let slice = core::slice::from_mut(val);
unsafe { Self::unchecked_mut(slice) }
}
#[inline]
pub const fn from_slice(slice: &[T]) -> Option<&Self> {
if !slice.is_empty() {
unsafe { Some(Self::unchecked(slice)) }
} else {
None
}
}
#[inline]
pub fn from_mut_slice(slice: &mut [T]) -> Option<&mut Self> {
if !slice.is_empty() {
unsafe { Some(Self::unchecked_mut(slice)) }
} else {
None
}
}
#[inline]
pub fn from_boxed_slice(slice: Box<[T]>) -> Option<Box<Self>> {
if !slice.is_empty() {
unsafe { Some(Self::unchecked_boxed(slice)) }
} else {
None
}
}
#[inline]
pub const fn as_slice(&self) -> &[T] {
&self.0
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [T] {
&mut self.0
}
#[inline]
pub fn into_boxed_slice(self: Box<Self>) -> Box<[T]> {
let ptr = Box::into_raw(self) as *mut [T];
unsafe { Box::from_raw(ptr) }
}
#[inline]
pub const fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.0.len()) }
}
#[inline]
pub const fn is_empty(&self) -> bool {
false
}
#[inline]
pub const fn as_ptr(&self) -> *const T {
self.0.as_ptr()
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
self.0.as_mut_ptr()
}
#[inline]
pub const fn first(&self) -> &T {
if let [first, ..] = self.as_slice() {
first
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub fn first_mut(&mut self) -> &mut T {
if let [first, ..] = self.as_mut_slice() {
first
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub const fn last(&self) -> &T {
if let [.., last] = self.as_slice() {
last
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub fn last_mut(&mut self) -> &mut T {
if let [.., last] = self.as_mut_slice() {
last
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub const fn split_first(&self) -> (&T, &[T]) {
if let [first, rest @ ..] = self.as_slice() {
(first, rest)
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub fn split_first_mut(&mut self) -> (&mut T, &mut [T]) {
if let [first, rest @ ..] = self.as_mut_slice() {
(first, rest)
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub fn split_last(&self) -> (&T, &[T]) {
if let [rest @ .., last] = self.as_slice() {
(last, rest)
} else {
unsafe { unreachable_unchecked!() }
}
}
#[inline]
pub fn split_last_mut(&mut self) -> (&mut T, &mut [T]) {
if let [rest @ .., last] = self.as_mut_slice() {
(last, rest)
} else {
unsafe { unreachable_unchecked!() }
}
}
}
impl<'a, T> TryFrom<&'a [T]> for &'a NonEmptySlice<T> {
type Error = EmptyError;
fn try_from(value: &'a [T]) -> Result<Self, Self::Error> {
NonEmptySlice::from_slice(value).ok_or(EmptyError)
}
}
impl<'a, T> TryFrom<&'a mut [T]> for &'a mut NonEmptySlice<T> {
type Error = EmptyError;
fn try_from(value: &'a mut [T]) -> Result<Self, Self::Error> {
NonEmptySlice::from_mut_slice(value).ok_or(EmptyError)
}
}
impl<T> TryFrom<Box<[T]>> for Box<NonEmptySlice<T>> {
type Error = EmptyError;
fn try_from(value: Box<[T]>) -> Result<Self, Self::Error> {
NonEmptySlice::from_boxed_slice(value).ok_or(EmptyError)
}
}
impl<T> Deref for NonEmptySlice<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<T> DerefMut for NonEmptySlice<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}
impl<T> AsRef<[T]> for NonEmptySlice<T> {
#[inline]
fn as_ref(&self) -> &[T] {
self
}
}
impl<T> AsMut<[T]> for NonEmptySlice<T> {
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self
}
}
impl<T: Debug> Debug for NonEmptySlice<T> {
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
write!(f, "{:?}", &self.0)
}
}
impl<T: PartialEq, U: ?Sized + AsRef<[T]>> PartialEq<U> for NonEmptySlice<T> {
#[inline]
fn eq(&self, other: &U) -> bool {
&self.0 == other.as_ref()
}
}
impl<T: PartialEq> PartialEq<NonEmptySlice<T>> for [T] {
#[inline]
fn eq(&self, other: &NonEmptySlice<T>) -> bool {
*self == other.0
}
}
impl<T: PartialOrd, U: ?Sized + AsRef<[T]>> PartialOrd<U> for NonEmptySlice<T> {
#[inline]
fn partial_cmp(&self, other: &U) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(other.as_ref())
}
}
impl<T: PartialOrd> PartialOrd<NonEmptySlice<T>> for [T] {
#[inline]
fn partial_cmp(&self, other: &NonEmptySlice<T>) -> Option<core::cmp::Ordering> {
self.partial_cmp(&other.0)
}
}
impl<'a, T> IntoIterator for &'a NonEmptySlice<T> {
type Item = &'a T;
type IntoIter = Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T> IntoIterator for &'a mut NonEmptySlice<T> {
type Item = &'a mut T;
type IntoIter = IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
#[doc(hidden)]
pub use alloc::vec as __vec;
#[macro_export]
macro_rules! ne_vec {
() => {
::core::compile_error!("`NonEmpty` vector must be non-empty")
};
($($x:expr),+ $(,)?) => {{
let vec = $crate::__vec![$($x),+];
unsafe { $crate::NonEmpty::new_unchecked(vec) }
}};
($elem:expr; 0) => {
$crate::ne_vec![]
};
($elem:expr; $n:literal) => {{
const _ASSERT_NON_ZERO: [(); $n - 1] = [(); $n - 1];
let vec = $crate::__vec![$elem; $n];
unsafe { $crate::NonEmpty::new_unchecked(vec) }
}};
($elem:expr; $n:expr) => {{
let len = $n;
if len == 0 {
::core::panic!("`NonEmpty` vector must be non-empty");
}
let vec = $crate::__vec![$elem; len];
unsafe { $crate::NonEmpty::new_unchecked(vec) }
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let mut list: NonEmpty<i32> = (vec![1, 2], 3).into();
assert_eq!(list, (1, vec![2, 3]).into());
assert_eq!(&*list, &[1, 2, 3]);
list[0] = 2;
assert_eq!(list[0], 2);
list[0] = 1;
assert_eq!(list[0], 1);
assert_eq!(list.len().get(), 3);
assert_eq!(list.as_slice(), &[1, 2, 3]);
assert_eq!(<NonEmpty<i32>>::try_from(vec![]).ok(), None);
assert_eq!(
&*<NonEmpty<i32>>::try_from(vec![1, 2, 3]).unwrap(),
&[1, 2, 3]
);
assert_eq!(
list.iter().map(|n| n * 2).collect::<Vec<_>>(),
vec![2, 4, 6]
);
let single = NonEmpty::new(15_i32);
assert_eq!(single.len().get(), 1);
assert_eq!(single[0], 15);
}
#[test]
fn default() {
assert_eq!(NonEmpty::<i32>::default(), ne_vec![0]);
assert_eq!(NonEmpty::<&str>::default(), ne_vec![""]);
}
#[test]
fn into_iter() {
let mut list = ne_vec![1, 2, 3];
for (a, b) in [1, 2, 3].iter().zip(&list) {
assert_eq!(a, b);
}
for a in &mut list {
*a += 1;
}
assert_eq!(list.as_slice(), &[2, 3, 4]);
for (a, b) in vec![2, 3, 4].into_iter().zip(list) {
assert_eq!(a, b);
}
}
#[test]
fn drain_filter() {
let mut v = ne_vec![1, 2, 3, 4, 5, 6];
assert!(v.drain_filter(|val| *val % 2 == 1).eq([1, 3, 5]));
assert_eq!(v, ne_vec![2, 4, 6]);
let mut v = ne_vec![1];
for _ in v.drain_filter(|_| unreachable!()) {}
assert_eq!(v, ne_vec![1]);
let mut v = ne_vec![1, 2, 3];
let removed = v.drain_filter(|&mut val| if val < 3 { true } else { unreachable!() });
assert!(removed.eq([1, 2]));
assert_eq!(v, ne_vec![3]);
let mut v = ne_vec![1, 2, 3, 4, 5, 6];
let mut rem = v.drain_filter(|val| *val % 2 == 1);
assert_eq!(rem.next(), Some(1));
assert_eq!(rem.next_back(), Some(5));
assert_eq!(rem.next_back(), Some(3));
assert_eq!(rem.next(), None);
assert_eq!(rem.next_back(), None);
let mut v = ne_vec![1, 2, 3, 4, 5, 6];
let rem = v.drain_filter(|val| *val % 2 == 0).rev();
assert!(rem.eq([6, 4, 2]));
assert_eq!(v, ne_vec![1, 3, 5]);
let mut v = ne_vec![1];
for _ in v.drain_filter(|_| unreachable!()) {}
assert_eq!(v, ne_vec![1]);
let mut v = ne_vec![1, 2, 3];
let removed = v
.drain_filter(|&mut val| if val > 1 { true } else { unreachable!() })
.rev();
assert!(removed.eq([3, 2]));
assert_eq!(v, ne_vec![1]);
let mut v = ne_vec![1, 2, 3];
let mut rem = v.drain_filter(|&mut val| if val == 2 { unreachable!() } else { true });
assert_eq!(rem.next_back(), Some(3));
assert_eq!(rem.next(), Some(1));
assert_eq!(rem.next_back(), None);
assert_eq!(rem.next(), None);
assert_eq!(v, ne_vec![2]);
}
#[test]
fn initialize_macro() {
assert_eq!(ne_vec![1; 3].as_slice(), &[1, 1, 1]);
assert_eq!(ne_vec!["string"; 5].as_slice(), &["string"; 5]);
}
#[test]
#[should_panic]
fn initialize_macro_zero_size() {
let n = 0;
let _ = ne_vec![1; n];
}
#[test]
fn initialize_macro_fake_vec() {
#[allow(unused_macros)]
macro_rules! vec {
($($x:tt)*) => {
Vec::new()
};
}
let list: NonEmpty<u32> = ne_vec![1, 2, 3];
assert_eq!(list.len().get(), 3);
}
#[cfg(feature = "serde")]
#[test]
fn serialize() {
let vec: NonEmpty<u32> = (1, vec![]).into();
assert_eq!(
serde_json::from_str::<NonEmpty<u32>>(&serde_json::to_string(&vec).unwrap()).unwrap(),
vec
);
}
}