use crate::TryFromIterator;
#[cfg(not(feature = "std"))]
use alloc::{vec, vec::Vec};
use bytes::{Buf, BufMut};
use commonware_codec::{EncodeSize, RangeCfg, Read, Write};
use core::{
num::NonZeroUsize,
ops::{Deref, DerefMut},
};
use thiserror::Error;
#[derive(Error, Debug, PartialEq, Eq)]
pub enum Error {
#[error("cannot create NonEmptyVec from empty collection")]
Empty,
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NonEmptyVec<T>(Vec<T>);
impl<T> NonEmptyVec<T> {
pub fn new(first: T) -> Self {
Self(vec![first])
}
pub fn from_unchecked(vec: Vec<T>) -> Self {
assert!(
!vec.is_empty(),
"NonEmptyVec::from_unchecked: vector is empty"
);
Self(vec)
}
pub const fn len(&self) -> NonZeroUsize {
NonZeroUsize::new(self.0.len()).unwrap()
}
pub const fn is_singleton(&self) -> bool {
self.0.len() == 1
}
pub fn first(&self) -> &T {
self.0.first().unwrap()
}
pub fn first_mut(&mut self) -> &mut T {
self.0.first_mut().unwrap()
}
pub fn last(&self) -> &T {
self.0.last().unwrap()
}
pub fn last_mut(&mut self) -> &mut T {
self.0.last_mut().unwrap()
}
pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> NonEmptyVec<U> {
NonEmptyVec(self.0.iter().map(f).collect())
}
pub fn map_into<U, F: FnMut(T) -> U>(self, f: F) -> NonEmptyVec<U> {
NonEmptyVec(self.0.into_iter().map(f).collect())
}
pub fn push(&mut self, value: T) {
self.0.push(value);
}
pub fn insert(&mut self, index: usize, element: T) {
self.0.insert(index, element);
}
pub fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.0.extend(iter);
}
pub fn resize(&mut self, new_len: NonZeroUsize, value: T)
where
T: Clone,
{
self.0.resize(new_len.get(), value);
}
pub fn resize_with<F>(&mut self, new_len: NonZeroUsize, f: F)
where
F: FnMut() -> T,
{
self.0.resize_with(new_len.get(), f);
}
pub fn pop(&mut self) -> Option<T> {
if self.0.len() > 1 {
self.0.pop()
} else {
None
}
}
pub fn remove(&mut self, index: usize) -> Option<T> {
assert!(index < self.0.len(), "index out of bounds");
if self.0.len() > 1 {
Some(self.0.remove(index))
} else {
None
}
}
pub fn mutate<F, R>(&mut self, f: F) -> R
where
F: FnOnce(&mut Vec<T>) -> R,
{
let result = f(&mut self.0);
assert!(
!self.0.is_empty(),
"NonEmptyVec::mutate: closure left vector empty"
);
result
}
pub fn into_vec(self) -> Vec<T> {
self.0
}
}
impl<T> Deref for NonEmptyVec<T> {
type Target = [T];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for NonEmptyVec<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<T> AsRef<[T]> for NonEmptyVec<T> {
fn as_ref(&self) -> &[T] {
&self.0
}
}
impl<T> AsRef<Vec<T>> for NonEmptyVec<T> {
fn as_ref(&self) -> &Vec<T> {
&self.0
}
}
impl<T> From<NonEmptyVec<T>> for Vec<T> {
fn from(vec: NonEmptyVec<T>) -> Self {
vec.0
}
}
impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
type Error = Error;
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
if vec.is_empty() {
Err(Error::Empty)
} else {
Ok(Self(vec))
}
}
}
impl<T: Clone> TryFrom<&[T]> for NonEmptyVec<T> {
type Error = Error;
fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
if slice.is_empty() {
Err(Error::Empty)
} else {
Ok(Self(slice.to_vec()))
}
}
}
impl<T, const N: usize> TryFrom<[T; N]> for NonEmptyVec<T> {
type Error = Error;
fn try_from(arr: [T; N]) -> Result<Self, Self::Error> {
if N == 0 {
Err(Error::Empty)
} else {
Ok(Self(arr.into()))
}
}
}
impl<T: Clone, const N: usize> TryFrom<&[T; N]> for NonEmptyVec<T> {
type Error = Error;
fn try_from(arr: &[T; N]) -> Result<Self, Self::Error> {
Self::try_from(arr.as_slice())
}
}
impl<T> TryFromIterator<T> for NonEmptyVec<T> {
type Error = Error;
fn try_from_iter<I: IntoIterator<Item = T>>(iter: I) -> Result<Self, Self::Error> {
let vec: Vec<T> = iter.into_iter().collect();
Self::try_from(vec)
}
}
impl<T> IntoIterator for NonEmptyVec<T> {
type Item = T;
type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
type Item = &'a T;
type IntoIter = core::slice::Iter<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, T> IntoIterator for &'a mut NonEmptyVec<T> {
type Item = &'a mut T;
type IntoIter = core::slice::IterMut<'a, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<T: Write> Write for NonEmptyVec<T> {
fn write(&self, buf: &mut impl BufMut) {
self.0.write(buf);
}
}
impl<T: EncodeSize> EncodeSize for NonEmptyVec<T> {
fn encode_size(&self) -> usize {
self.0.encode_size()
}
}
impl<T: Read> Read for NonEmptyVec<T> {
type Cfg = (RangeCfg<NonZeroUsize>, T::Cfg);
fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<Self, commonware_codec::Error> {
let items = Vec::read_cfg(buf, &(cfg.0.into(), cfg.1.clone()))?;
if items.is_empty() {
return Err(commonware_codec::Error::Invalid(
"NonEmptyVec",
"cannot decode empty vector",
));
}
Ok(Self(items))
}
}
#[cfg(feature = "arbitrary")]
impl<'a, T: arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for NonEmptyVec<T> {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
let first: T = u.arbitrary()?;
let rest: Vec<T> = u.arbitrary()?;
let mut vec = Vec::with_capacity(1 + rest.len());
vec.push(first);
vec.extend(rest);
Ok(Self(vec))
}
}
#[macro_export]
macro_rules! non_empty_vec {
(@$vec:expr) => {{
$crate::vec::NonEmptyVec::from_unchecked($vec)
}};
($elem:expr; NZUsize!($n:expr)) => {{
$crate::vec::NonEmptyVec::from_unchecked(vec![$elem; $crate::NZUsize!($n).get()])
}};
($elem:expr; @$n:expr) => {{
let n: core::num::NonZeroUsize = $n;
$crate::vec::NonEmptyVec::from_unchecked(vec![$elem; n.get()])
}};
($elem:expr; $n:expr) => {{
const N: usize = $n;
const _: () = assert!(N > 0, "count must be greater than 0");
$crate::vec::NonEmptyVec::from_unchecked(vec![$elem; N])
}};
($first:expr $(, $rest:expr)* $(,)?) => {
$crate::vec::NonEmptyVec::from_unchecked(vec![$first $(, $rest)*])
};
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{NZUsize, TryCollect};
use commonware_codec::{EncodeSize, Error as CodecError, RangeCfg, Read, Write};
use std::num::NonZeroUsize;
#[test]
fn test_new() {
let v = NonEmptyVec::new(42);
assert_eq!(v.len().get(), 1);
assert_eq!(v.first(), &42);
assert_eq!(v.last(), &42);
}
#[test]
#[should_panic(expected = "vector is empty")]
fn test_from_unchecked_panics_on_empty() {
let _: NonEmptyVec<i32> = NonEmptyVec::from_unchecked(vec![]);
}
#[test]
fn test_is_singleton() {
let v = non_empty_vec![42];
assert!(v.is_singleton());
let v = non_empty_vec![1, 2];
assert!(!v.is_singleton());
let v = non_empty_vec![1, 2, 3];
assert!(!v.is_singleton());
}
#[test]
fn test_macro() {
let v = non_empty_vec![1, 2, 3];
assert_eq!(v.len().get(), 3);
assert_eq!(v.first(), &1);
assert_eq!(v.last(), &3);
let v = non_empty_vec![42];
assert_eq!(v.len().get(), 1);
assert_eq!(v.first(), &42);
let v = non_empty_vec![1, 2, 3,];
assert_eq!(v.len().get(), 3);
let v = non_empty_vec![42; 5];
assert_eq!(v.len().get(), 5);
assert!(v.iter().all(|&x| x == 42));
let v = non_empty_vec![0; 1];
assert_eq!(v.len().get(), 1);
assert_eq!(v.first(), &0);
let v = non_empty_vec![99; NZUsize!(3)];
assert_eq!(v.len().get(), 3);
assert!(v.iter().all(|&x| x == 99));
let n = NonZeroUsize::new(4).unwrap();
let v = non_empty_vec![7; @n];
assert_eq!(v.len().get(), 4);
assert!(v.iter().all(|&x| x == 7));
let vec = vec![1, 2, 3];
let v = non_empty_vec![@vec];
assert_eq!(v.len().get(), 3);
assert_eq!(&*v, &[1, 2, 3]);
}
#[test]
fn test_try_from_vec() {
let v: NonEmptyVec<i32> = vec![1, 2, 3].try_into().unwrap();
assert_eq!(v.len().get(), 3);
let result: Result<NonEmptyVec<i32>, _> = Vec::new().try_into();
assert_eq!(result, Err(Error::Empty));
}
#[test]
fn test_try_from_slice() {
let v: NonEmptyVec<i32> = [1, 2, 3].as_slice().try_into().unwrap();
assert_eq!(v.len().get(), 3);
let empty: &[i32] = &[];
let result: Result<NonEmptyVec<i32>, _> = empty.try_into();
assert_eq!(result, Err(Error::Empty));
}
#[test]
fn test_try_from_array() {
let v: NonEmptyVec<i32> = [1, 2, 3].try_into().unwrap();
assert_eq!(v.len().get(), 3);
let result: Result<NonEmptyVec<i32>, _> = [0i32; 0].try_into();
assert_eq!(result, Err(Error::Empty));
}
#[test]
fn test_try_from_iterator() {
let v: NonEmptyVec<i32> = (1..=3).try_collect().unwrap();
assert_eq!(v.len().get(), 3);
let result: Result<NonEmptyVec<i32>, _> = core::iter::empty().try_collect();
assert_eq!(result, Err(Error::Empty));
}
#[test]
fn test_first_last() {
let mut v = non_empty_vec![1, 2, 3];
assert_eq!(v.first(), &1);
assert_eq!(v.last(), &3);
*v.first_mut() = 10;
*v.last_mut() = 30;
assert_eq!(v.first(), &10);
assert_eq!(v.last(), &30);
}
#[test]
fn test_push() {
let mut v = non_empty_vec![1];
v.push(2);
v.push(3);
assert_eq!(v.len().get(), 3);
assert_eq!(v.last(), &3);
}
#[test]
fn test_insert() {
let mut v = non_empty_vec![1, 3];
v.insert(1, 2);
assert_eq!(&*v, &[1, 2, 3]);
}
#[test]
fn test_extend() {
let mut v = non_empty_vec![1];
v.extend([2, 3, 4]);
assert_eq!(v.len().get(), 4);
assert_eq!(&*v, &[1, 2, 3, 4]);
}
#[test]
fn test_resize() {
let mut v = non_empty_vec![1, 2];
v.resize(NonZeroUsize::new(5).unwrap(), 0);
assert_eq!(&*v, &[1, 2, 0, 0, 0]);
v.resize(NonZeroUsize::new(2).unwrap(), 0);
assert_eq!(&*v, &[1, 2]);
v.resize(NonZeroUsize::new(1).unwrap(), 0);
assert_eq!(&*v, &[1]);
}
#[test]
fn test_resize_with() {
let mut counter = 0;
let mut v = non_empty_vec![1];
v.resize_with(NonZeroUsize::new(4).unwrap(), || {
counter += 1;
counter * 10
});
assert_eq!(&*v, &[1, 10, 20, 30]);
v.resize_with(NonZeroUsize::new(2).unwrap(), || {
panic!("should not be called")
});
assert_eq!(&*v, &[1, 10]);
}
#[test]
fn test_pop() {
let mut v = non_empty_vec![1, 2, 3];
assert_eq!(v.pop(), Some(3));
assert_eq!(v.len().get(), 2);
assert_eq!(v.pop(), Some(2));
assert_eq!(v.len().get(), 1);
assert_eq!(v.pop(), None);
assert_eq!(v.len().get(), 1);
assert_eq!(v.first(), &1);
}
#[test]
fn test_remove() {
let mut v = non_empty_vec![1, 2, 3];
assert_eq!(v.remove(1), Some(2));
assert_eq!(&*v, &[1, 3]);
assert_eq!(v.remove(0), Some(1));
assert_eq!(&*v, &[3]);
assert_eq!(v.remove(0), None);
assert_eq!(&*v, &[3]);
}
#[test]
fn test_mutate() {
let mut v = non_empty_vec![3, 1, 2, 1];
v.mutate(|vec| {
vec.sort();
vec.dedup();
});
assert_eq!(&*v, &[1, 2, 3]);
let mut v = non_empty_vec![1, 2, 3];
let sum: i32 = v.mutate(|vec| vec.iter().sum());
assert_eq!(sum, 6);
}
#[test]
#[should_panic(expected = "closure left vector empty")]
fn test_mutate_panics_on_empty() {
let mut v = non_empty_vec![1];
v.mutate(|vec| vec.clear());
}
#[test]
fn test_deref() {
let v = non_empty_vec![3, 1, 2];
assert_eq!(v.len().get(), 3);
assert!(v.contains(&2));
assert_eq!(v.get(1), Some(&1));
}
#[test]
fn test_deref_mut() {
let mut v = non_empty_vec![3, 1, 2];
v.sort();
assert_eq!(&*v, &[1, 2, 3]);
v.reverse();
assert_eq!(&*v, &[3, 2, 1]);
v.swap(0, 2);
assert_eq!(&*v, &[1, 2, 3]);
}
#[test]
fn test_into_vec() {
let v = non_empty_vec![1, 2, 3];
let vec: Vec<i32> = v.into_vec();
assert_eq!(vec, vec![1, 2, 3]);
}
#[test]
fn test_map() {
let v = non_empty_vec![1, 2, 3];
let doubled = v.map(|x| x * 2);
assert_eq!(&*doubled, &[2, 4, 6]);
assert_eq!(&*v, &[1, 2, 3]);
}
#[test]
fn test_map_into() {
let v = non_empty_vec![1, 2, 3];
let doubled = v.map_into(|x| x * 2);
assert_eq!(&*doubled, &[2, 4, 6]);
}
#[test]
fn test_from_non_empty_vec() {
let v = non_empty_vec![1, 2, 3];
let vec: Vec<i32> = v.into();
assert_eq!(vec, vec![1, 2, 3]);
}
#[test]
fn test_index() {
let v = non_empty_vec![1, 2, 3];
assert_eq!(v[0], 1);
assert_eq!(v[1], 2);
assert_eq!(v[2], 3);
assert_eq!(&v[0..2], &[1, 2]);
let mut v = non_empty_vec![1, 2, 3];
v[0] = 10;
v[1..3].copy_from_slice(&[20, 30]);
assert_eq!(&*v, &[10, 20, 30]);
}
#[test]
fn test_iterators() {
let v = non_empty_vec![1, 2, 3];
let sum: i32 = v.iter().sum();
assert_eq!(sum, 6);
let mut v = non_empty_vec![1, 2, 3];
for x in v.iter_mut() {
*x *= 2;
}
assert_eq!(&*v, &[2, 4, 6]);
let v = non_empty_vec![1, 2, 3];
let collected: Vec<_> = v.into_iter().collect();
assert_eq!(collected, vec![1, 2, 3]);
let v = non_empty_vec![1, 2, 3];
let collected: Vec<_> = (&v).into_iter().copied().collect();
assert_eq!(collected, vec![1, 2, 3]);
let mut v = non_empty_vec![1, 2, 3];
for x in &mut v {
*x += 10;
}
assert_eq!(&*v, &[11, 12, 13]);
}
#[test]
fn test_codec_roundtrip() {
let v = non_empty_vec![1u8, 2, 3];
let mut buf = Vec::with_capacity(v.encode_size());
v.write(&mut buf);
let decoded = NonEmptyVec::<u8>::read_cfg(
&mut buf.as_slice(),
&(RangeCfg::from(NZUsize!(1)..=NZUsize!(10)), ()),
)
.unwrap();
assert_eq!(v, decoded);
}
#[test]
fn test_codec_rejects_empty() {
let empty: Vec<u8> = vec![];
let mut buf = Vec::new();
empty.write(&mut buf);
let result = NonEmptyVec::<u8>::read_cfg(&mut buf.as_slice(), &(RangeCfg::from(..), ()));
assert!(matches!(
result,
Err(CodecError::Invalid(
"NonEmptyVec",
"cannot decode empty vector"
))
));
let result =
NonEmptyVec::<u8>::read_cfg(&mut buf.as_slice(), &(RangeCfg::from(..NZUsize!(10)), ()));
assert!(matches!(
result,
Err(CodecError::Invalid(
"NonEmptyVec",
"cannot decode empty vector"
))
));
let result = NonEmptyVec::<u8>::read_cfg(
&mut buf.as_slice(),
&(RangeCfg::from(NZUsize!(1)..NZUsize!(10)), ()),
);
assert!(matches!(result, Err(CodecError::InvalidLength(0))));
}
#[test]
fn test_as_ref() {
let v = non_empty_vec![1, 2, 3];
let slice: &[i32] = v.as_ref();
assert_eq!(slice, &[1, 2, 3]);
let vec_ref: &Vec<i32> = v.as_ref();
assert_eq!(vec_ref, &vec![1, 2, 3]);
}
}