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 {
216            self.0.pop()
217        } else {
218            None
219        }
220    }
221
222    /// Removes and returns the element at position `index`, or `None` if
223    /// removing would leave the vector empty.
224    ///
225    /// This ensures the vector always has at least one element.
226    ///
227    /// # Panics
228    ///
229    /// Panics if `index >= len`.
230    pub fn remove(&mut self, index: usize) -> Option<T> {
231        assert!(index < self.0.len(), "index out of bounds");
232        if self.0.len() > 1 {
233            Some(self.0.remove(index))
234        } else {
235            None
236        }
237    }
238
239    /// Provides mutable access to the underlying vector via a closure.
240    ///
241    /// This is an escape hatch for operations not directly exposed by `NonEmptyVec`.
242    ///
243    /// # Panics
244    ///
245    /// Panics if the closure leaves the vector empty.
246    ///
247    /// # Examples
248    ///
249    /// ```
250    /// use commonware_utils::non_empty_vec;
251    ///
252    /// let mut v = non_empty_vec![3, 1, 2];
253    /// v.mutate(|vec| vec.sort());
254    /// assert_eq!(v.first(), &1);
255    /// ```
256    pub fn mutate<F, R>(&mut self, f: F) -> R
257    where
258        F: FnOnce(&mut Vec<T>) -> R,
259    {
260        let result = f(&mut self.0);
261        assert!(
262            !self.0.is_empty(),
263            "NonEmptyVec::mutate: closure left vector empty"
264        );
265        result
266    }
267
268    /// Consumes the [`NonEmptyVec`] and returns the underlying [`Vec`].
269    pub fn into_vec(self) -> Vec<T> {
270        self.0
271    }
272}
273
274impl<T> Deref for NonEmptyVec<T> {
275    type Target = [T];
276
277    fn deref(&self) -> &Self::Target {
278        &self.0
279    }
280}
281
282impl<T> DerefMut for NonEmptyVec<T> {
283    fn deref_mut(&mut self) -> &mut Self::Target {
284        &mut self.0
285    }
286}
287
288impl<T> AsRef<[T]> for NonEmptyVec<T> {
289    fn as_ref(&self) -> &[T] {
290        &self.0
291    }
292}
293
294impl<T> AsRef<Vec<T>> for NonEmptyVec<T> {
295    fn as_ref(&self) -> &Vec<T> {
296        &self.0
297    }
298}
299
300impl<T> From<NonEmptyVec<T>> for Vec<T> {
301    fn from(vec: NonEmptyVec<T>) -> Self {
302        vec.0
303    }
304}
305
306impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
307    type Error = Error;
308
309    fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
310        if vec.is_empty() {
311            Err(Error::Empty)
312        } else {
313            Ok(Self(vec))
314        }
315    }
316}
317
318impl<T: Clone> TryFrom<&[T]> for NonEmptyVec<T> {
319    type Error = Error;
320
321    fn try_from(slice: &[T]) -> Result<Self, Self::Error> {
322        if slice.is_empty() {
323            Err(Error::Empty)
324        } else {
325            Ok(Self(slice.to_vec()))
326        }
327    }
328}
329
330impl<T, const N: usize> TryFrom<[T; N]> for NonEmptyVec<T> {
331    type Error = Error;
332
333    fn try_from(arr: [T; N]) -> Result<Self, Self::Error> {
334        if N == 0 {
335            Err(Error::Empty)
336        } else {
337            Ok(Self(arr.into()))
338        }
339    }
340}
341
342impl<T: Clone, const N: usize> TryFrom<&[T; N]> for NonEmptyVec<T> {
343    type Error = Error;
344
345    fn try_from(arr: &[T; N]) -> Result<Self, Self::Error> {
346        Self::try_from(arr.as_slice())
347    }
348}
349
350impl<T> TryFromIterator<T> for NonEmptyVec<T> {
351    type Error = Error;
352
353    fn try_from_iter<I: IntoIterator<Item = T>>(iter: I) -> Result<Self, Self::Error> {
354        let vec: Vec<T> = iter.into_iter().collect();
355        Self::try_from(vec)
356    }
357}
358
359impl<T> IntoIterator for NonEmptyVec<T> {
360    type Item = T;
361    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
362
363    fn into_iter(self) -> Self::IntoIter {
364        self.0.into_iter()
365    }
366}
367
368impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
369    type Item = &'a T;
370    type IntoIter = core::slice::Iter<'a, T>;
371
372    fn into_iter(self) -> Self::IntoIter {
373        self.0.iter()
374    }
375}
376
377impl<'a, T> IntoIterator for &'a mut NonEmptyVec<T> {
378    type Item = &'a mut T;
379    type IntoIter = core::slice::IterMut<'a, T>;
380
381    fn into_iter(self) -> Self::IntoIter {
382        self.0.iter_mut()
383    }
384}
385
386impl<T: Write> Write for NonEmptyVec<T> {
387    fn write(&self, buf: &mut impl BufMut) {
388        self.0.write(buf);
389    }
390}
391
392impl<T: EncodeSize> EncodeSize for NonEmptyVec<T> {
393    fn encode_size(&self) -> usize {
394        self.0.encode_size()
395    }
396}
397
398impl<T: Read> Read for NonEmptyVec<T> {
399    type Cfg = (RangeCfg<NonZeroUsize>, T::Cfg);
400
401    fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<Self, commonware_codec::Error> {
402        let items = Vec::read_cfg(buf, &(cfg.0.into(), cfg.1.clone()))?;
403        if items.is_empty() {
404            return Err(commonware_codec::Error::Invalid(
405                "NonEmptyVec",
406                "cannot decode empty vector",
407            ));
408        }
409        Ok(Self(items))
410    }
411}
412
413#[cfg(feature = "arbitrary")]
414impl<'a, T: arbitrary::Arbitrary<'a>> arbitrary::Arbitrary<'a> for NonEmptyVec<T> {
415    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
416        let first: T = u.arbitrary()?;
417        let rest: Vec<T> = u.arbitrary()?;
418        let mut vec = Vec::with_capacity(1 + rest.len());
419        vec.push(first);
420        vec.extend(rest);
421        Ok(Self(vec))
422    }
423}
424
425/// Creates a [`NonEmptyVec`] containing the given elements.
426///
427/// # Forms
428///
429/// | Syntax | Count type | Guarantee |
430/// |--------|------------|-----------|
431/// | `non_empty_vec![a, b, c]` | - | Compile-time (at least one element required) |
432/// | `non_empty_vec![elem; N]` | const `usize` | Compile-time (N must be const and > 0) |
433/// | `non_empty_vec![elem; NZUsize!(N)]` | [`NZUsize!`] | Runtime (panics if N == 0) |
434/// | `non_empty_vec![elem; @n]` | [`NonZeroUsize`] | Type-safe (n is already non-zero) |
435/// | `non_empty_vec![@v]` | - | Runtime (panics if v is empty) |
436///
437/// The `@` marker is required for runtime [`NonZeroUsize`] values to distinguish
438/// them from const `usize` values, since declarative macros cannot inspect types.
439///
440/// [`NZUsize!`]: crate::NZUsize
441///
442/// # Examples
443///
444/// ```
445/// use commonware_utils::{non_empty_vec, NZUsize};
446///
447/// // List form
448/// let v = non_empty_vec![1, 2, 3];
449/// assert_eq!(v.len().get(), 3);
450///
451/// // Const repeat: N must be a const expression > 0
452/// let v = non_empty_vec![42; 5];
453/// assert_eq!(v.len().get(), 5);
454///
455/// // NZUsize! form: convenient for inline literals
456/// let v = non_empty_vec![42; NZUsize!(3)];
457/// assert_eq!(v.len().get(), 3);
458///
459/// // Runtime form: use @ with any NonZeroUsize expression
460/// let n = NZUsize!(2);
461/// let v = non_empty_vec![42; @n];
462/// assert_eq!(v.len().get(), 2);
463///
464/// // Vec form: wrap an existing Vec (panics if empty)
465/// let vec = vec![1, 2, 3];
466/// let v = non_empty_vec![@vec];
467/// assert_eq!(v.len().get(), 3);
468/// ```
469///
470/// # Compile Errors
471///
472/// ```compile_fail
473/// use commonware_utils::non_empty_vec;
474/// let empty = non_empty_vec![]; // error: no elements
475/// ```
476///
477/// ```compile_fail
478/// use commonware_utils::non_empty_vec;
479/// let zero = non_empty_vec![42; 0]; // error: count is 0
480/// ```
481///
482/// ```compile_fail
483/// use commonware_utils::non_empty_vec;
484/// let n: usize = 5;
485/// let v = non_empty_vec![42; n]; // error: n is not const (use @n with NonZeroUsize)
486/// ```
487#[macro_export]
488macro_rules! non_empty_vec {
489    (@$vec:expr) => {{
490        $crate::vec::NonEmptyVec::from_unchecked($vec)
491    }};
492    ($elem:expr; NZUsize!($n:expr)) => {{
493        $crate::vec::NonEmptyVec::from_unchecked(vec![$elem; $crate::NZUsize!($n).get()])
494    }};
495    ($elem:expr; @$n:expr) => {{
496        let n: core::num::NonZeroUsize = $n;
497        $crate::vec::NonEmptyVec::from_unchecked(vec![$elem; n.get()])
498    }};
499    ($elem:expr; $n:expr) => {{
500        const N: usize = $n;
501        const _: () = assert!(N > 0, "count must be greater than 0");
502        $crate::vec::NonEmptyVec::from_unchecked(vec![$elem; N])
503    }};
504    ($first:expr $(, $rest:expr)* $(,)?) => {
505        $crate::vec::NonEmptyVec::from_unchecked(vec![$first $(, $rest)*])
506    };
507}
508
509#[cfg(test)]
510mod tests {
511    use super::*;
512    use crate::{NZUsize, TryCollect};
513    use commonware_codec::{EncodeSize, Error as CodecError, RangeCfg, Read, Write};
514    use std::num::NonZeroUsize;
515
516    #[test]
517    fn test_bounded_push_evicts_oldest() {
518        let mut deque = Bounded::new(NZUsize!(3));
519
520        assert_eq!(deque.push(1), None);
521        assert_eq!(deque.push(2), None);
522        assert_eq!(deque.push(3), None);
523        assert_eq!(deque.push(4), Some(1));
524
525        assert_eq!(deque.capacity().get(), 3);
526        assert_eq!(deque.iter().copied().collect::<Vec<_>>(), vec![2, 3, 4]);
527    }
528
529    #[test]
530    fn test_bounded_pop_front_reuses_capacity() {
531        let mut deque = Bounded::new(NZUsize!(2));
532
533        assert_eq!(deque.push(1), None);
534        assert_eq!(deque.push(2), None);
535        assert_eq!(deque.pop_front(), Some(1));
536        assert_eq!(deque.push(3), None);
537
538        assert_eq!(deque.iter().copied().collect::<Vec<_>>(), vec![2, 3]);
539    }
540
541    #[test]
542    fn test_bounded_into_inner() {
543        let mut deque = Bounded::new(NZUsize!(2));
544
545        deque.push(1);
546        deque.push(2);
547
548        assert_eq!(
549            deque.into_inner().into_iter().collect::<Vec<_>>(),
550            vec![1, 2]
551        );
552    }
553
554    #[test]
555    fn test_new() {
556        let v = NonEmptyVec::new(42);
557        assert_eq!(v.len().get(), 1);
558        assert_eq!(v.first(), &42);
559        assert_eq!(v.last(), &42);
560    }
561
562    #[test]
563    #[should_panic(expected = "vector is empty")]
564    fn test_from_unchecked_panics_on_empty() {
565        let _: NonEmptyVec<i32> = NonEmptyVec::from_unchecked(vec![]);
566    }
567
568    #[test]
569    fn test_is_singleton() {
570        let v = non_empty_vec![42];
571        assert!(v.is_singleton());
572
573        let v = non_empty_vec![1, 2];
574        assert!(!v.is_singleton());
575
576        let v = non_empty_vec![1, 2, 3];
577        assert!(!v.is_singleton());
578    }
579
580    #[test]
581    fn test_macro() {
582        let v = non_empty_vec![1, 2, 3];
583        assert_eq!(v.len().get(), 3);
584        assert_eq!(v.first(), &1);
585        assert_eq!(v.last(), &3);
586
587        let v = non_empty_vec![42];
588        assert_eq!(v.len().get(), 1);
589        assert_eq!(v.first(), &42);
590
591        // Trailing comma support
592        let v = non_empty_vec![1, 2, 3,];
593        assert_eq!(v.len().get(), 3);
594
595        // Const repeat syntax
596        let v = non_empty_vec![42; 5];
597        assert_eq!(v.len().get(), 5);
598        assert!(v.iter().all(|&x| x == 42));
599
600        let v = non_empty_vec![0; 1];
601        assert_eq!(v.len().get(), 1);
602        assert_eq!(v.first(), &0);
603
604        // NZUsize! macro form
605        let v = non_empty_vec![99; NZUsize!(3)];
606        assert_eq!(v.len().get(), 3);
607        assert!(v.iter().all(|&x| x == 99));
608
609        // Runtime repeat syntax with NonZeroUsize variable
610        let n = NonZeroUsize::new(4).unwrap();
611        let v = non_empty_vec![7; @n];
612        assert_eq!(v.len().get(), 4);
613        assert!(v.iter().all(|&x| x == 7));
614
615        // Vec wrap syntax
616        let vec = vec![1, 2, 3];
617        let v = non_empty_vec![@vec];
618        assert_eq!(v.len().get(), 3);
619        assert_eq!(&*v, &[1, 2, 3]);
620    }
621
622    #[test]
623    fn test_try_from_vec() {
624        let v: NonEmptyVec<i32> = vec![1, 2, 3].try_into().unwrap();
625        assert_eq!(v.len().get(), 3);
626
627        let result: Result<NonEmptyVec<i32>, _> = Vec::new().try_into();
628        assert_eq!(result, Err(Error::Empty));
629    }
630
631    #[test]
632    fn test_try_from_slice() {
633        let v: NonEmptyVec<i32> = [1, 2, 3].as_slice().try_into().unwrap();
634        assert_eq!(v.len().get(), 3);
635
636        let empty: &[i32] = &[];
637        let result: Result<NonEmptyVec<i32>, _> = empty.try_into();
638        assert_eq!(result, Err(Error::Empty));
639    }
640
641    #[test]
642    fn test_try_from_array() {
643        let v: NonEmptyVec<i32> = [1, 2, 3].try_into().unwrap();
644        assert_eq!(v.len().get(), 3);
645
646        let result: Result<NonEmptyVec<i32>, _> = [0i32; 0].try_into();
647        assert_eq!(result, Err(Error::Empty));
648    }
649
650    #[test]
651    fn test_try_from_iterator() {
652        let v: NonEmptyVec<i32> = (1..=3).try_collect().unwrap();
653        assert_eq!(v.len().get(), 3);
654
655        let result: Result<NonEmptyVec<i32>, _> = core::iter::empty().try_collect();
656        assert_eq!(result, Err(Error::Empty));
657    }
658
659    #[test]
660    fn test_first_last() {
661        let mut v = non_empty_vec![1, 2, 3];
662
663        assert_eq!(v.first(), &1);
664        assert_eq!(v.last(), &3);
665
666        *v.first_mut() = 10;
667        *v.last_mut() = 30;
668
669        assert_eq!(v.first(), &10);
670        assert_eq!(v.last(), &30);
671    }
672
673    #[test]
674    fn test_push() {
675        let mut v = non_empty_vec![1];
676        v.push(2);
677        v.push(3);
678        assert_eq!(v.len().get(), 3);
679        assert_eq!(v.last(), &3);
680    }
681
682    #[test]
683    fn test_insert() {
684        let mut v = non_empty_vec![1, 3];
685        v.insert(1, 2);
686        assert_eq!(&*v, &[1, 2, 3]);
687    }
688
689    #[test]
690    fn test_extend() {
691        let mut v = non_empty_vec![1];
692        v.extend([2, 3, 4]);
693        assert_eq!(v.len().get(), 4);
694        assert_eq!(&*v, &[1, 2, 3, 4]);
695    }
696
697    #[test]
698    fn test_resize() {
699        // Grow
700        let mut v = non_empty_vec![1, 2];
701        v.resize(NonZeroUsize::new(5).unwrap(), 0);
702        assert_eq!(&*v, &[1, 2, 0, 0, 0]);
703
704        // Shrink
705        v.resize(NonZeroUsize::new(2).unwrap(), 0);
706        assert_eq!(&*v, &[1, 2]);
707
708        // Shrink to 1 (minimum)
709        v.resize(NonZeroUsize::new(1).unwrap(), 0);
710        assert_eq!(&*v, &[1]);
711    }
712
713    #[test]
714    fn test_resize_with() {
715        let mut counter = 0;
716        let mut v = non_empty_vec![1];
717        v.resize_with(NonZeroUsize::new(4).unwrap(), || {
718            counter += 1;
719            counter * 10
720        });
721        assert_eq!(&*v, &[1, 10, 20, 30]);
722
723        // Shrink (closure not called)
724        v.resize_with(NonZeroUsize::new(2).unwrap(), || {
725            panic!("should not be called")
726        });
727        assert_eq!(&*v, &[1, 10]);
728    }
729
730    #[test]
731    fn test_pop() {
732        let mut v = non_empty_vec![1, 2, 3];
733
734        assert_eq!(v.pop(), Some(3));
735        assert_eq!(v.len().get(), 2);
736
737        assert_eq!(v.pop(), Some(2));
738        assert_eq!(v.len().get(), 1);
739
740        // Cannot pop the last element
741        assert_eq!(v.pop(), None);
742        assert_eq!(v.len().get(), 1);
743        assert_eq!(v.first(), &1);
744    }
745
746    #[test]
747    fn test_remove() {
748        let mut v = non_empty_vec![1, 2, 3];
749
750        assert_eq!(v.remove(1), Some(2));
751        assert_eq!(&*v, &[1, 3]);
752
753        assert_eq!(v.remove(0), Some(1));
754        assert_eq!(&*v, &[3]);
755
756        // Cannot remove the last element
757        assert_eq!(v.remove(0), None);
758        assert_eq!(&*v, &[3]);
759    }
760
761    #[test]
762    fn test_mutate() {
763        let mut v = non_empty_vec![3, 1, 2, 1];
764        v.mutate(|vec| {
765            vec.sort();
766            vec.dedup();
767        });
768        assert_eq!(&*v, &[1, 2, 3]);
769
770        // Test that return value is propagated
771        let mut v = non_empty_vec![1, 2, 3];
772        let sum: i32 = v.mutate(|vec| vec.iter().sum());
773        assert_eq!(sum, 6);
774    }
775
776    #[test]
777    #[should_panic(expected = "closure left vector empty")]
778    fn test_mutate_panics_on_empty() {
779        let mut v = non_empty_vec![1];
780        v.mutate(|vec| vec.clear());
781    }
782
783    #[test]
784    fn test_deref() {
785        let v = non_empty_vec![3, 1, 2];
786
787        // slice methods via Deref
788        assert_eq!(v.len().get(), 3);
789        assert!(v.contains(&2));
790        assert_eq!(v.get(1), Some(&1));
791    }
792
793    #[test]
794    fn test_deref_mut() {
795        let mut v = non_empty_vec![3, 1, 2];
796
797        // Mutable slice methods via DerefMut
798        v.sort();
799        assert_eq!(&*v, &[1, 2, 3]);
800
801        v.reverse();
802        assert_eq!(&*v, &[3, 2, 1]);
803
804        v.swap(0, 2);
805        assert_eq!(&*v, &[1, 2, 3]);
806    }
807
808    #[test]
809    fn test_into_vec() {
810        let v = non_empty_vec![1, 2, 3];
811        let vec: Vec<i32> = v.into_vec();
812        assert_eq!(vec, vec![1, 2, 3]);
813    }
814
815    #[test]
816    fn test_map() {
817        let v = non_empty_vec![1, 2, 3];
818        let doubled = v.map(|x| x * 2);
819        assert_eq!(&*doubled, &[2, 4, 6]);
820
821        // Original unchanged
822        assert_eq!(&*v, &[1, 2, 3]);
823    }
824
825    #[test]
826    fn test_map_into() {
827        let v = non_empty_vec![1, 2, 3];
828        let doubled = v.map_into(|x| x * 2);
829        assert_eq!(&*doubled, &[2, 4, 6]);
830    }
831
832    #[test]
833    fn test_from_non_empty_vec() {
834        let v = non_empty_vec![1, 2, 3];
835        let vec: Vec<i32> = v.into();
836        assert_eq!(vec, vec![1, 2, 3]);
837    }
838
839    #[test]
840    fn test_index() {
841        let v = non_empty_vec![1, 2, 3];
842        assert_eq!(v[0], 1);
843        assert_eq!(v[1], 2);
844        assert_eq!(v[2], 3);
845        assert_eq!(&v[0..2], &[1, 2]);
846
847        // IndexMut
848        let mut v = non_empty_vec![1, 2, 3];
849        v[0] = 10;
850        v[1..3].copy_from_slice(&[20, 30]);
851        assert_eq!(&*v, &[10, 20, 30]);
852    }
853
854    #[test]
855    fn test_iterators() {
856        let v = non_empty_vec![1, 2, 3];
857
858        // iter()
859        let sum: i32 = v.iter().sum();
860        assert_eq!(sum, 6);
861
862        // iter_mut()
863        let mut v = non_empty_vec![1, 2, 3];
864        for x in v.iter_mut() {
865            *x *= 2;
866        }
867        assert_eq!(&*v, &[2, 4, 6]);
868
869        // IntoIterator (owned)
870        let v = non_empty_vec![1, 2, 3];
871        let collected: Vec<_> = v.into_iter().collect();
872        assert_eq!(collected, vec![1, 2, 3]);
873
874        // IntoIterator (borrowed)
875        let v = non_empty_vec![1, 2, 3];
876        let collected: Vec<_> = (&v).into_iter().copied().collect();
877        assert_eq!(collected, vec![1, 2, 3]);
878
879        // IntoIterator (borrowed mut)
880        let mut v = non_empty_vec![1, 2, 3];
881        for x in &mut v {
882            *x += 10;
883        }
884        assert_eq!(&*v, &[11, 12, 13]);
885    }
886
887    #[test]
888    fn test_codec_roundtrip() {
889        let v = non_empty_vec![1u8, 2, 3];
890
891        let mut buf = Vec::with_capacity(v.encode_size());
892        v.write(&mut buf);
893
894        let decoded = NonEmptyVec::<u8>::read_cfg(
895            &mut buf.as_slice(),
896            &(RangeCfg::from(NZUsize!(1)..=NZUsize!(10)), ()),
897        )
898        .unwrap();
899
900        assert_eq!(v, decoded);
901    }
902
903    #[test]
904    fn test_codec_rejects_empty() {
905        let empty: Vec<u8> = vec![];
906        let mut buf = Vec::new();
907        empty.write(&mut buf);
908
909        let result = NonEmptyVec::<u8>::read_cfg(&mut buf.as_slice(), &(RangeCfg::from(..), ()));
910        assert!(matches!(
911            result,
912            Err(CodecError::Invalid(
913                "NonEmptyVec",
914                "cannot decode empty vector"
915            ))
916        ));
917
918        let result =
919            NonEmptyVec::<u8>::read_cfg(&mut buf.as_slice(), &(RangeCfg::from(..NZUsize!(10)), ()));
920        assert!(matches!(
921            result,
922            Err(CodecError::Invalid(
923                "NonEmptyVec",
924                "cannot decode empty vector"
925            ))
926        ));
927
928        let result = NonEmptyVec::<u8>::read_cfg(
929            &mut buf.as_slice(),
930            &(RangeCfg::from(NZUsize!(1)..NZUsize!(10)), ()),
931        );
932        assert!(matches!(result, Err(CodecError::InvalidLength(0))));
933    }
934
935    #[test]
936    fn test_as_ref() {
937        let v = non_empty_vec![1, 2, 3];
938
939        let slice: &[i32] = v.as_ref();
940        assert_eq!(slice, &[1, 2, 3]);
941
942        let vec_ref: &Vec<i32> = v.as_ref();
943        assert_eq!(vec_ref, &vec![1, 2, 3]);
944    }
945}