commonware_utils/
vec.rs

1//! A vector type that guarantees at least one element.
2
3use crate::TryFromIterator;
4#[cfg(not(feature = "std"))]
5use alloc::{vec, vec::Vec};
6use bytes::{Buf, BufMut};
7use commonware_codec::{EncodeSize, RangeCfg, Read, Write};
8use core::{
9    num::NonZeroUsize,
10    ops::{Deref, DerefMut},
11};
12use thiserror::Error;
13
14/// Errors that can occur when creating a [`NonEmptyVec`].
15#[derive(Error, Debug, PartialEq, Eq)]
16pub enum Error {
17    /// The collection was empty.
18    #[error("cannot create NonEmptyVec from empty collection")]
19    Empty,
20}
21
22/// A vector that is guaranteed to contain at least one element.
23#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub struct NonEmptyVec<T>(Vec<T>);
25
26impl<T> NonEmptyVec<T> {
27    /// Creates a new [`NonEmptyVec`] with a single element.
28    pub fn new(first: T) -> Self {
29        Self(vec![first])
30    }
31
32    /// Creates a [`NonEmptyVec`] from a [`Vec`] without returning a `Result`.
33    ///
34    /// # Panics
35    ///
36    /// Panics if the vector is empty.
37    pub fn from_unchecked(vec: Vec<T>) -> Self {
38        assert!(
39            !vec.is_empty(),
40            "NonEmptyVec::from_unchecked: vector is empty"
41        );
42        Self(vec)
43    }
44
45    /// Returns the number of elements in the vector.
46    ///
47    /// This is guaranteed to be at least 1.
48    pub const fn len(&self) -> NonZeroUsize {
49        NonZeroUsize::new(self.0.len()).unwrap()
50    }
51
52    /// Returns `true` if the vector contains exactly one element.
53    pub const fn is_singleton(&self) -> bool {
54        self.0.len() == 1
55    }
56
57    /// Returns a reference to the first element.
58    ///
59    /// Unlike [`slice::first`], this doesn't return an `Option`.
60    pub fn first(&self) -> &T {
61        self.0.first().unwrap()
62    }
63
64    /// Returns a mutable reference to the first element.
65    ///
66    /// Unlike [`slice::first_mut`], this doesn't return an `Option`.
67    pub fn first_mut(&mut self) -> &mut T {
68        self.0.first_mut().unwrap()
69    }
70
71    /// Returns a reference to the last element.
72    ///
73    /// Unlike [`slice::last`], this doesn't return an `Option`.
74    pub fn last(&self) -> &T {
75        self.0.last().unwrap()
76    }
77
78    /// Returns a mutable reference to the last element.
79    ///
80    /// Unlike [`slice::last_mut`], this doesn't return an `Option`.
81    pub fn last_mut(&mut self) -> &mut T {
82        self.0.last_mut().unwrap()
83    }
84
85    /// Maps each element to a new value, preserving the non-empty guarantee.
86    pub fn map<U, F: FnMut(&T) -> U>(&self, f: F) -> NonEmptyVec<U> {
87        NonEmptyVec(self.0.iter().map(f).collect())
88    }
89
90    /// Consumes the vector and maps each element to a new value.
91    pub fn map_into<U, F: FnMut(T) -> U>(self, f: F) -> NonEmptyVec<U> {
92        NonEmptyVec(self.0.into_iter().map(f).collect())
93    }
94
95    /// Appends an element to the back of the vector.
96    pub fn push(&mut self, value: T) {
97        self.0.push(value);
98    }
99
100    /// Inserts an element at position `index`.
101    ///
102    /// # Panics
103    ///
104    /// Panics if `index > len`.
105    pub fn insert(&mut self, index: usize, element: T) {
106        self.0.insert(index, element);
107    }
108
109    /// Extends the vector with the contents of an iterator.
110    pub fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
111        self.0.extend(iter);
112    }
113
114    /// Resizes the vector to the specified length.
115    ///
116    /// If `new_len` is greater than `len()`, the vector is extended with clones
117    /// of `value`. If `new_len` is less than `len()`, the vector is truncated.
118    ///
119    /// Unlike [`Vec::resize`], this takes [`NonZeroUsize`] to maintain the
120    /// non-empty guarantee.
121    pub fn resize(&mut self, new_len: NonZeroUsize, value: T)
122    where
123        T: Clone,
124    {
125        self.0.resize(new_len.get(), value);
126    }
127
128    /// Resizes the vector to the specified length using a closure.
129    ///
130    /// If `new_len` is greater than `len()`, the vector is extended with values
131    /// generated by calling `f` repeatedly. If `new_len` is less than `len()`,
132    /// the vector is truncated.
133    ///
134    /// Unlike [`Vec::resize_with`], this takes [`NonZeroUsize`] to maintain the
135    /// non-empty guarantee.
136    pub fn resize_with<F>(&mut self, new_len: NonZeroUsize, f: F)
137    where
138        F: FnMut() -> T,
139    {
140        self.0.resize_with(new_len.get(), f);
141    }
142
143    /// Removes the last element and returns it, or `None` if there is only one
144    /// element.
145    ///
146    /// This ensures the vector always has at least one element.
147    pub fn pop(&mut self) -> Option<T> {
148        if self.0.len() > 1 {
149            self.0.pop()
150        } else {
151            None
152        }
153    }
154
155    /// Removes and returns the element at position `index`, or `None` if
156    /// removing would leave the vector empty.
157    ///
158    /// This ensures the vector always has at least one element.
159    ///
160    /// # Panics
161    ///
162    /// Panics if `index >= len`.
163    pub fn remove(&mut self, index: usize) -> Option<T> {
164        assert!(index < self.0.len(), "index out of bounds");
165        if self.0.len() > 1 {
166            Some(self.0.remove(index))
167        } else {
168            None
169        }
170    }
171
172    /// Provides mutable access to the underlying vector via a closure.
173    ///
174    /// This is an escape hatch for operations not directly exposed by `NonEmptyVec`.
175    ///
176    /// # Panics
177    ///
178    /// Panics if the closure leaves the vector empty.
179    ///
180    /// # Examples
181    ///
182    /// ```
183    /// use commonware_utils::non_empty_vec;
184    ///
185    /// let mut v = non_empty_vec![3, 1, 2];
186    /// v.mutate(|vec| vec.sort());
187    /// assert_eq!(v.first(), &1);
188    /// ```
189    pub fn mutate<F, R>(&mut self, f: F) -> R
190    where
191        F: FnOnce(&mut Vec<T>) -> R,
192    {
193        let result = f(&mut self.0);
194        assert!(
195            !self.0.is_empty(),
196            "NonEmptyVec::mutate: closure left vector empty"
197        );
198        result
199    }
200
201    /// Consumes the [`NonEmptyVec`] and returns the underlying [`Vec`].
202    pub fn into_vec(self) -> Vec<T> {
203        self.0
204    }
205}
206
207impl<T> Deref for NonEmptyVec<T> {
208    type Target = [T];
209
210    fn deref(&self) -> &Self::Target {
211        &self.0
212    }
213}
214
215impl<T> DerefMut for NonEmptyVec<T> {
216    fn deref_mut(&mut self) -> &mut Self::Target {
217        &mut self.0
218    }
219}
220
221impl<T> AsRef<[T]> for NonEmptyVec<T> {
222    fn as_ref(&self) -> &[T] {
223        &self.0
224    }
225}
226
227impl<T> AsRef<Vec<T>> for NonEmptyVec<T> {
228    fn as_ref(&self) -> &Vec<T> {
229        &self.0
230    }
231}
232
233impl<T> From<NonEmptyVec<T>> for Vec<T> {
234    fn from(vec: NonEmptyVec<T>) -> Self {
235        vec.0
236    }
237}
238
239impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
240    type Error = Error;
241
242    fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
243        if vec.is_empty() {
244            Err(Error::Empty)
245        } else {
246            Ok(Self(vec))
247        }
248    }
249}
250
251impl<T: Clone> TryFrom<&[T]> for NonEmptyVec<T> {
252    type Error = Error;
253
254    fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
255        if slice.is_empty() {
256            Err(Error::Empty)
257        } else {
258            Ok(Self(slice.to_vec()))
259        }
260    }
261}
262
263impl<T, const N: usize> TryFrom<[T; N]> for NonEmptyVec<T> {
264    type Error = Error;
265
266    fn try_from(arr: [T; N]) -> Result<Self, Self::Error> {
267        if N == 0 {
268            Err(Error::Empty)
269        } else {
270            Ok(Self(arr.into()))
271        }
272    }
273}
274
275impl<T: Clone, const N: usize> TryFrom<&[T; N]> for NonEmptyVec<T> {
276    type Error = Error;
277
278    fn try_from(arr: &[T; N]) -> Result<Self, Self::Error> {
279        Self::try_from(arr.as_slice())
280    }
281}
282
283impl<T> TryFromIterator<T> for NonEmptyVec<T> {
284    type Error = Error;
285
286    fn try_from_iter<I: IntoIterator<Item = T>>(iter: I) -> Result<Self, Self::Error> {
287        let vec: Vec<T> = iter.into_iter().collect();
288        Self::try_from(vec)
289    }
290}
291
292impl<T> IntoIterator for NonEmptyVec<T> {
293    type Item = T;
294    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
295
296    fn into_iter(self) -> Self::IntoIter {
297        self.0.into_iter()
298    }
299}
300
301impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
302    type Item = &'a T;
303    type IntoIter = core::slice::Iter<'a, T>;
304
305    fn into_iter(self) -> Self::IntoIter {
306        self.0.iter()
307    }
308}
309
310impl<'a, T> IntoIterator for &'a mut NonEmptyVec<T> {
311    type Item = &'a mut T;
312    type IntoIter = core::slice::IterMut<'a, T>;
313
314    fn into_iter(self) -> Self::IntoIter {
315        self.0.iter_mut()
316    }
317}
318
319impl<T: Write> Write for NonEmptyVec<T> {
320    fn write(&self, buf: &mut impl BufMut) {
321        self.0.write(buf);
322    }
323}
324
325impl<T: EncodeSize> EncodeSize for NonEmptyVec<T> {
326    fn encode_size(&self) -> usize {
327        self.0.encode_size()
328    }
329}
330
331impl<T: Read> Read for NonEmptyVec<T> {
332    type Cfg = (RangeCfg<NonZeroUsize>, T::Cfg);
333
334    fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<Self, commonware_codec::Error> {
335        let items = Vec::read_cfg(buf, &(cfg.0.into(), cfg.1.clone()))?;
336        if items.is_empty() {
337            return Err(commonware_codec::Error::Invalid(
338                "NonEmptyVec",
339                "cannot decode empty vector",
340            ));
341        }
342        Ok(Self(items))
343    }
344}
345
346#[cfg(feature = "arbitrary")]
347impl<'a, T: arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for NonEmptyVec<T> {
348    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
349        let first: T = u.arbitrary()?;
350        let rest: Vec<T> = u.arbitrary()?;
351        let mut vec = Vec::with_capacity(1 + rest.len());
352        vec.push(first);
353        vec.extend(rest);
354        Ok(Self(vec))
355    }
356}
357
358/// Creates a [`NonEmptyVec`] containing the given elements.
359///
360/// # Forms
361///
362/// | Syntax | Count type | Guarantee |
363/// |--------|------------|-----------|
364/// | `non_empty_vec![a, b, c]` | - | Compile-time (at least one element required) |
365/// | `non_empty_vec![elem; N]` | const `usize` | Compile-time (N must be const and > 0) |
366/// | `non_empty_vec![elem; NZUsize!(N)]` | [`NZUsize!`] | Runtime (panics if N == 0) |
367/// | `non_empty_vec![elem; @n]` | [`NonZeroUsize`] | Type-safe (n is already non-zero) |
368/// | `non_empty_vec![@v]` | - | Runtime (panics if v is empty) |
369///
370/// The `@` marker is required for runtime [`NonZeroUsize`] values to distinguish
371/// them from const `usize` values, since declarative macros cannot inspect types.
372///
373/// [`NZUsize!`]: crate::NZUsize
374///
375/// # Examples
376///
377/// ```
378/// use commonware_utils::{non_empty_vec, NZUsize};
379///
380/// // List form
381/// let v = non_empty_vec![1, 2, 3];
382/// assert_eq!(v.len().get(), 3);
383///
384/// // Const repeat: N must be a const expression > 0
385/// let v = non_empty_vec![42; 5];
386/// assert_eq!(v.len().get(), 5);
387///
388/// // NZUsize! form: convenient for inline literals
389/// let v = non_empty_vec![42; NZUsize!(3)];
390/// assert_eq!(v.len().get(), 3);
391///
392/// // Runtime form: use @ with any NonZeroUsize expression
393/// let n = NZUsize!(2);
394/// let v = non_empty_vec![42; @n];
395/// assert_eq!(v.len().get(), 2);
396///
397/// // Vec form: wrap an existing Vec (panics if empty)
398/// let vec = vec![1, 2, 3];
399/// let v = non_empty_vec![@vec];
400/// assert_eq!(v.len().get(), 3);
401/// ```
402///
403/// # Compile Errors
404///
405/// ```compile_fail
406/// use commonware_utils::non_empty_vec;
407/// let empty = non_empty_vec![]; // error: no elements
408/// ```
409///
410/// ```compile_fail
411/// use commonware_utils::non_empty_vec;
412/// let zero = non_empty_vec![42; 0]; // error: count is 0
413/// ```
414///
415/// ```compile_fail
416/// use commonware_utils::non_empty_vec;
417/// let n: usize = 5;
418/// let v = non_empty_vec![42; n]; // error: n is not const (use @n with NonZeroUsize)
419/// ```
420#[macro_export]
421macro_rules! non_empty_vec {
422    (@$vec:expr) => {{
423        $crate::vec::NonEmptyVec::from_unchecked($vec)
424    }};
425    ($elem:expr; NZUsize!($n:expr)) => {{
426        $crate::vec::NonEmptyVec::from_unchecked(vec![$elem; $crate::NZUsize!($n).get()])
427    }};
428    ($elem:expr; @$n:expr) => {{
429        let n: core::num::NonZeroUsize = $n;
430        $crate::vec::NonEmptyVec::from_unchecked(vec![$elem; n.get()])
431    }};
432    ($elem:expr; $n:expr) => {{
433        const N: usize = $n;
434        const _: () = assert!(N > 0, "count must be greater than 0");
435        $crate::vec::NonEmptyVec::from_unchecked(vec![$elem; N])
436    }};
437    ($first:expr $(, $rest:expr)* $(,)?) => {
438        $crate::vec::NonEmptyVec::from_unchecked(vec![$first $(, $rest)*])
439    };
440}
441
442#[cfg(test)]
443mod tests {
444    use super::*;
445    use crate::{NZUsize, TryCollect};
446    use commonware_codec::Error as CodecError;
447    use std::num::NonZeroUsize;
448
449    #[test]
450    fn test_new() {
451        let v = NonEmptyVec::new(42);
452        assert_eq!(v.len().get(), 1);
453        assert_eq!(v.first(), &42);
454        assert_eq!(v.last(), &42);
455    }
456
457    #[test]
458    #[should_panic(expected = "vector is empty")]
459    fn test_from_unchecked_panics_on_empty() {
460        let _: NonEmptyVec<i32> = NonEmptyVec::from_unchecked(vec![]);
461    }
462
463    #[test]
464    fn test_is_singleton() {
465        let v = non_empty_vec![42];
466        assert!(v.is_singleton());
467
468        let v = non_empty_vec![1, 2];
469        assert!(!v.is_singleton());
470
471        let v = non_empty_vec![1, 2, 3];
472        assert!(!v.is_singleton());
473    }
474
475    #[test]
476    fn test_macro() {
477        let v = non_empty_vec![1, 2, 3];
478        assert_eq!(v.len().get(), 3);
479        assert_eq!(v.first(), &1);
480        assert_eq!(v.last(), &3);
481
482        let v = non_empty_vec![42];
483        assert_eq!(v.len().get(), 1);
484        assert_eq!(v.first(), &42);
485
486        // Trailing comma support
487        let v = non_empty_vec![1, 2, 3,];
488        assert_eq!(v.len().get(), 3);
489
490        // Const repeat syntax
491        let v = non_empty_vec![42; 5];
492        assert_eq!(v.len().get(), 5);
493        assert!(v.iter().all(|&x| x == 42));
494
495        let v = non_empty_vec![0; 1];
496        assert_eq!(v.len().get(), 1);
497        assert_eq!(v.first(), &0);
498
499        // NZUsize! macro form
500        let v = non_empty_vec![99; NZUsize!(3)];
501        assert_eq!(v.len().get(), 3);
502        assert!(v.iter().all(|&x| x == 99));
503
504        // Runtime repeat syntax with NonZeroUsize variable
505        let n = NonZeroUsize::new(4).unwrap();
506        let v = non_empty_vec![7; @n];
507        assert_eq!(v.len().get(), 4);
508        assert!(v.iter().all(|&x| x == 7));
509
510        // Vec wrap syntax
511        let vec = vec![1, 2, 3];
512        let v = non_empty_vec![@vec];
513        assert_eq!(v.len().get(), 3);
514        assert_eq!(&*v, &[1, 2, 3]);
515    }
516
517    #[test]
518    fn test_try_from_vec() {
519        let v: NonEmptyVec<i32> = vec![1, 2, 3].try_into().unwrap();
520        assert_eq!(v.len().get(), 3);
521
522        let result: Result<NonEmptyVec<i32>, _> = Vec::new().try_into();
523        assert_eq!(result, Err(Error::Empty));
524    }
525
526    #[test]
527    fn test_try_from_slice() {
528        let v: NonEmptyVec<i32> = [1, 2, 3].as_slice().try_into().unwrap();
529        assert_eq!(v.len().get(), 3);
530
531        let empty: &[i32] = &[];
532        let result: Result<NonEmptyVec<i32>, _> = empty.try_into();
533        assert_eq!(result, Err(Error::Empty));
534    }
535
536    #[test]
537    fn test_try_from_array() {
538        let v: NonEmptyVec<i32> = [1, 2, 3].try_into().unwrap();
539        assert_eq!(v.len().get(), 3);
540
541        let result: Result<NonEmptyVec<i32>, _> = [0i32; 0].try_into();
542        assert_eq!(result, Err(Error::Empty));
543    }
544
545    #[test]
546    fn test_try_from_iterator() {
547        let v: NonEmptyVec<i32> = (1..=3).try_collect().unwrap();
548        assert_eq!(v.len().get(), 3);
549
550        let result: Result<NonEmptyVec<i32>, _> = core::iter::empty().try_collect();
551        assert_eq!(result, Err(Error::Empty));
552    }
553
554    #[test]
555    fn test_first_last() {
556        let mut v = non_empty_vec![1, 2, 3];
557
558        assert_eq!(v.first(), &1);
559        assert_eq!(v.last(), &3);
560
561        *v.first_mut() = 10;
562        *v.last_mut() = 30;
563
564        assert_eq!(v.first(), &10);
565        assert_eq!(v.last(), &30);
566    }
567
568    #[test]
569    fn test_push() {
570        let mut v = non_empty_vec![1];
571        v.push(2);
572        v.push(3);
573        assert_eq!(v.len().get(), 3);
574        assert_eq!(v.last(), &3);
575    }
576
577    #[test]
578    fn test_insert() {
579        let mut v = non_empty_vec![1, 3];
580        v.insert(1, 2);
581        assert_eq!(&*v, &[1, 2, 3]);
582    }
583
584    #[test]
585    fn test_extend() {
586        let mut v = non_empty_vec![1];
587        v.extend([2, 3, 4]);
588        assert_eq!(v.len().get(), 4);
589        assert_eq!(&*v, &[1, 2, 3, 4]);
590    }
591
592    #[test]
593    fn test_resize() {
594        // Grow
595        let mut v = non_empty_vec![1, 2];
596        v.resize(NonZeroUsize::new(5).unwrap(), 0);
597        assert_eq!(&*v, &[1, 2, 0, 0, 0]);
598
599        // Shrink
600        v.resize(NonZeroUsize::new(2).unwrap(), 0);
601        assert_eq!(&*v, &[1, 2]);
602
603        // Shrink to 1 (minimum)
604        v.resize(NonZeroUsize::new(1).unwrap(), 0);
605        assert_eq!(&*v, &[1]);
606    }
607
608    #[test]
609    fn test_resize_with() {
610        let mut counter = 0;
611        let mut v = non_empty_vec![1];
612        v.resize_with(NonZeroUsize::new(4).unwrap(), || {
613            counter += 1;
614            counter * 10
615        });
616        assert_eq!(&*v, &[1, 10, 20, 30]);
617
618        // Shrink (closure not called)
619        v.resize_with(NonZeroUsize::new(2).unwrap(), || {
620            panic!("should not be called")
621        });
622        assert_eq!(&*v, &[1, 10]);
623    }
624
625    #[test]
626    fn test_pop() {
627        let mut v = non_empty_vec![1, 2, 3];
628
629        assert_eq!(v.pop(), Some(3));
630        assert_eq!(v.len().get(), 2);
631
632        assert_eq!(v.pop(), Some(2));
633        assert_eq!(v.len().get(), 1);
634
635        // Cannot pop the last element
636        assert_eq!(v.pop(), None);
637        assert_eq!(v.len().get(), 1);
638        assert_eq!(v.first(), &1);
639    }
640
641    #[test]
642    fn test_remove() {
643        let mut v = non_empty_vec![1, 2, 3];
644
645        assert_eq!(v.remove(1), Some(2));
646        assert_eq!(&*v, &[1, 3]);
647
648        assert_eq!(v.remove(0), Some(1));
649        assert_eq!(&*v, &[3]);
650
651        // Cannot remove the last element
652        assert_eq!(v.remove(0), None);
653        assert_eq!(&*v, &[3]);
654    }
655
656    #[test]
657    fn test_mutate() {
658        let mut v = non_empty_vec![3, 1, 2, 1];
659        v.mutate(|vec| {
660            vec.sort();
661            vec.dedup();
662        });
663        assert_eq!(&*v, &[1, 2, 3]);
664
665        // Test that return value is propagated
666        let mut v = non_empty_vec![1, 2, 3];
667        let sum: i32 = v.mutate(|vec| vec.iter().sum());
668        assert_eq!(sum, 6);
669    }
670
671    #[test]
672    #[should_panic(expected = "closure left vector empty")]
673    fn test_mutate_panics_on_empty() {
674        let mut v = non_empty_vec![1];
675        v.mutate(|vec| vec.clear());
676    }
677
678    #[test]
679    fn test_deref() {
680        let v = non_empty_vec![3, 1, 2];
681
682        // slice methods via Deref
683        assert_eq!(v.len().get(), 3);
684        assert!(v.contains(&2));
685        assert_eq!(v.get(1), Some(&1));
686    }
687
688    #[test]
689    fn test_deref_mut() {
690        let mut v = non_empty_vec![3, 1, 2];
691
692        // Mutable slice methods via DerefMut
693        v.sort();
694        assert_eq!(&*v, &[1, 2, 3]);
695
696        v.reverse();
697        assert_eq!(&*v, &[3, 2, 1]);
698
699        v.swap(0, 2);
700        assert_eq!(&*v, &[1, 2, 3]);
701    }
702
703    #[test]
704    fn test_into_vec() {
705        let v = non_empty_vec![1, 2, 3];
706        let vec: Vec<i32> = v.into_vec();
707        assert_eq!(vec, vec![1, 2, 3]);
708    }
709
710    #[test]
711    fn test_map() {
712        let v = non_empty_vec![1, 2, 3];
713        let doubled = v.map(|x| x * 2);
714        assert_eq!(&*doubled, &[2, 4, 6]);
715
716        // Original unchanged
717        assert_eq!(&*v, &[1, 2, 3]);
718    }
719
720    #[test]
721    fn test_map_into() {
722        let v = non_empty_vec![1, 2, 3];
723        let doubled = v.map_into(|x| x * 2);
724        assert_eq!(&*doubled, &[2, 4, 6]);
725    }
726
727    #[test]
728    fn test_from_non_empty_vec() {
729        let v = non_empty_vec![1, 2, 3];
730        let vec: Vec<i32> = v.into();
731        assert_eq!(vec, vec![1, 2, 3]);
732    }
733
734    #[test]
735    fn test_index() {
736        let v = non_empty_vec![1, 2, 3];
737        assert_eq!(v[0], 1);
738        assert_eq!(v[1], 2);
739        assert_eq!(v[2], 3);
740        assert_eq!(&v[0..2], &[1, 2]);
741
742        // IndexMut
743        let mut v = non_empty_vec![1, 2, 3];
744        v[0] = 10;
745        v[1..3].copy_from_slice(&[20, 30]);
746        assert_eq!(&*v, &[10, 20, 30]);
747    }
748
749    #[test]
750    fn test_iterators() {
751        let v = non_empty_vec![1, 2, 3];
752
753        // iter()
754        let sum: i32 = v.iter().sum();
755        assert_eq!(sum, 6);
756
757        // iter_mut()
758        let mut v = non_empty_vec![1, 2, 3];
759        for x in v.iter_mut() {
760            *x *= 2;
761        }
762        assert_eq!(&*v, &[2, 4, 6]);
763
764        // IntoIterator (owned)
765        let v = non_empty_vec![1, 2, 3];
766        let collected: Vec<_> = v.into_iter().collect();
767        assert_eq!(collected, vec![1, 2, 3]);
768
769        // IntoIterator (borrowed)
770        let v = non_empty_vec![1, 2, 3];
771        let collected: Vec<_> = (&v).into_iter().copied().collect();
772        assert_eq!(collected, vec![1, 2, 3]);
773
774        // IntoIterator (borrowed mut)
775        let mut v = non_empty_vec![1, 2, 3];
776        for x in &mut v {
777            *x += 10;
778        }
779        assert_eq!(&*v, &[11, 12, 13]);
780    }
781
782    #[test]
783    fn test_codec_roundtrip() {
784        let v = non_empty_vec![1u8, 2, 3];
785
786        let mut buf = Vec::with_capacity(v.encode_size());
787        v.write(&mut buf);
788
789        let decoded = NonEmptyVec::<u8>::read_cfg(
790            &mut buf.as_slice(),
791            &(RangeCfg::from(NZUsize!(1)..=NZUsize!(10)), ()),
792        )
793        .unwrap();
794
795        assert_eq!(v, decoded);
796    }
797
798    #[test]
799    fn test_codec_rejects_empty() {
800        let empty: Vec<u8> = vec![];
801        let mut buf = Vec::new();
802        empty.write(&mut buf);
803
804        let result = NonEmptyVec::<u8>::read_cfg(&mut buf.as_slice(), &(RangeCfg::from(..), ()));
805        assert!(matches!(
806            result,
807            Err(CodecError::Invalid(
808                "NonEmptyVec",
809                "cannot decode empty vector"
810            ))
811        ));
812
813        let result =
814            NonEmptyVec::<u8>::read_cfg(&mut buf.as_slice(), &(RangeCfg::from(..NZUsize!(10)), ()));
815        assert!(matches!(
816            result,
817            Err(CodecError::Invalid(
818                "NonEmptyVec",
819                "cannot decode empty vector"
820            ))
821        ));
822
823        let result = NonEmptyVec::<u8>::read_cfg(
824            &mut buf.as_slice(),
825            &(RangeCfg::from(NZUsize!(1)..NZUsize!(10)), ()),
826        );
827        assert!(matches!(result, Err(CodecError::InvalidLength(0))));
828    }
829
830    #[test]
831    fn test_as_ref() {
832        let v = non_empty_vec![1, 2, 3];
833
834        let slice: &[i32] = v.as_ref();
835        assert_eq!(slice, &[1, 2, 3]);
836
837        let vec_ref: &Vec<i32> = v.as_ref();
838        assert_eq!(vec_ref, &vec![1, 2, 3]);
839    }
840}