Skip to main content

commonware_utils/
vec.rs

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