nonempty_containers/nonemptyvec.rs
1//! A non-empty vector type that guarantees at least one element is present. [NonEmptyVec] has an
2//! interface similar to [Vec] with additional methods to enforce the invariant. Get started with:
3//!
4//! ```rust, no_run
5//! # use nonempty_containers::NonEmptyVec;
6//! #
7//! let nev = NonEmptyVec::new(42, vec![1, 2, 3]);
8//! let singleton = NonEmptyVec::singleton(42);
9//! ```
10//!
11//! [NonEmptyVec] conforms to [Index], [IntoIterator], [Deref], and many more, so operations are
12//! as [Vec]-like as possible. They are also usually zero-cost.
13//!
14//! ```rust, no_run
15//! # use nonempty_containers::NonEmptyVec;
16//! #
17//! let nev = NonEmptyVec::new(42, vec![1, 2, 3]);
18//! assert_eq!(nev[0], 42);
19//! assert_eq!(nev.len(), 4);
20//! assert_eq!(nev.into_iter().sum::<i32>(), 48);
21//! ```
22//!
23//! When the feature `arbitrary` is enabled, [NonEmptyVec] implements [arbitrary::Arbitrary]
24//! for generation of randomly populated instances.
25
26use std::ops::{Deref, Index};
27use std::slice::{Iter, IterMut};
28use std::vec::IntoIter;
29
30/// Non-empty vector type.
31#[derive(Debug, Eq, PartialEq, Clone, Hash)]
32pub struct NonEmptyVec<T>(Vec<T>);
33
34/// Errors that can occur when working with [NonEmptyVec].
35#[derive(Debug)]
36pub enum NonEmptyError {
37 /// Encountered an empty [Vec] when it was expected to be non-empty.
38 VecEmpty,
39
40 /// Attempted to remove an element from a singleton [NonEmptyVec].
41 AlreadySingleton,
42}
43
44impl<T> NonEmptyVec<T> {
45 /// Creates a new [NonEmptyVec], ensuring at least one element is present.
46 pub fn new(head: T, tail: Vec<T>) -> Self {
47 // We can afford to call [Vec::len()] here because it's O(1).
48 let mut vec = Vec::with_capacity(1 + tail.len());
49 vec.push(head);
50 vec.extend(tail);
51 Self(vec)
52 }
53
54 /// Creates a new singleton [NonEmptyVec]. Semantically equivalent to:
55 /// ```no_run
56 /// # use nonempty_containers::NonEmptyVec;
57 /// # let value = 42;
58 /// #
59 /// NonEmptyVec::new(value, Vec::new());
60 /// ```
61 pub fn singleton(value: T) -> Self {
62 Self(vec![value])
63 }
64
65 /// Returns the first element. This operation is safe as the invariant guarantees at least one
66 /// element is present.
67 pub fn head(&self) -> &T {
68 &self.0[0]
69 }
70
71 /// Returns the initial elements. This slice may be empty if the [NonEmptyVec] is a singleton.
72 pub fn init(&self) -> &[T] {
73 &self.0[..self.0.len() - 1]
74 }
75
76 /// Returns the tail as a slice. This slice may be empty if the [NonEmptyVec] is a singleton.
77 pub fn tail(&self) -> &[T] {
78 &self.0[1..]
79 }
80
81 /// Returns the last element. This operation is safe as the invariant guarantees at least one
82 /// element is present.
83 pub fn last(&self) -> &T {
84 self.0.last().unwrap()
85 }
86
87 /// Attempts to create a [NonEmptyVec] from a [Vec], returning [None] if the [Vec] is empty.
88 /// ```rust
89 /// # use nonempty_containers::NonEmptyVec;
90 /// #
91 /// assert!(NonEmptyVec::from_vec(vec![42]).is_ok());
92 /// assert!(NonEmptyVec::from_vec(Vec::<u32>::new()).is_err());
93 /// ```
94 pub fn from_vec(vec: Vec<T>) -> Result<Self, NonEmptyError> {
95 match vec.is_empty() {
96 true => Err(NonEmptyError::VecEmpty),
97 false => Ok(Self(vec)),
98 }
99 }
100
101 /// Creates a new [NonEmptyVec] from a [Vec] without checking if it's empty. This operation is
102 /// unsafe and should only be used by macros in this crate!
103 #[doc(hidden)]
104 pub fn __from_vec_unsafe(vec: Vec<T>) -> Self {
105 debug_assert!(!vec.is_empty());
106 Self(vec)
107 }
108
109 /// Extracts the inner [Vec], consuming [self]. This operation is zero-cost.
110 pub fn into_vec(self) -> Vec<T> {
111 self.0
112 }
113
114 /// Returns the length of this [NonEmptyVec].
115 pub fn len(&self) -> usize {
116 self.0.len()
117 }
118
119 /// A [NonEmptyVec] is always non-empty.
120 pub fn is_empty(&self) -> bool {
121 false
122 }
123
124 /// Returns this [NonEmptyVec] as a slice.
125 pub fn as_slice(&self) -> &[T] {
126 &self.0
127 }
128
129 /// Appends an element.
130 pub fn push(&mut self, value: T) {
131 self.0.push(value);
132 }
133
134 /// Tries to remove the last element, returning [NonEmptyError::AlreadySingleton] if the
135 /// [NonEmptyVec] would become empty.
136 pub fn pop(&mut self) -> Result<T, NonEmptyError> {
137 match self.0.len() {
138 0 => Err(NonEmptyError::VecEmpty),
139 1 => Err(NonEmptyError::AlreadySingleton),
140 _ => Ok(self.0.pop().unwrap()),
141 }
142 }
143}
144
145impl<T> From<NonEmptyVec<T>> for Vec<T> {
146 fn from(ne: NonEmptyVec<T>) -> Self {
147 ne.0
148 }
149}
150
151impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
152 type Error = NonEmptyError;
153
154 fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
155 NonEmptyVec::from_vec(vec)
156 }
157}
158
159impl<T> From<(T, Vec<T>)> for NonEmptyVec<T> {
160 fn from(value: (T, Vec<T>)) -> Self {
161 let (head, tail) = value;
162 Self::new(head, tail)
163 }
164}
165
166impl<T> From<T> for NonEmptyVec<T> {
167 fn from(value: T) -> Self {
168 Self::singleton(value)
169 }
170}
171
172impl<T> Deref for NonEmptyVec<T> {
173 type Target = [T];
174
175 fn deref(&self) -> &Self::Target {
176 &self.0
177 }
178}
179
180impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
181 type Item = &'a T;
182 type IntoIter = Iter<'a, T>;
183
184 fn into_iter(self) -> Self::IntoIter {
185 self.0.iter()
186 }
187}
188
189impl<'a, T> IntoIterator for &'a mut NonEmptyVec<T> {
190 type Item = &'a mut T;
191 type IntoIter = IterMut<'a, T>;
192
193 fn into_iter(self) -> Self::IntoIter {
194 self.0.iter_mut()
195 }
196}
197
198impl<T> IntoIterator for NonEmptyVec<T> {
199 type Item = T;
200 type IntoIter = IntoIter<T>;
201
202 fn into_iter(self) -> Self::IntoIter {
203 self.0.into_iter()
204 }
205}
206
207impl<T> Index<usize> for NonEmptyVec<T> {
208 type Output = T;
209
210 fn index(&self, index: usize) -> &Self::Output {
211 &self.0[index]
212 }
213}