reliakit_primitives/
collections.rs1use crate::{PrimitiveError, PrimitiveResult};
2use alloc::vec::Vec;
3use core::ops::Deref;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct NonEmptyVec<T>(Vec<T>);
8
9impl<T> NonEmptyVec<T> {
10 pub fn new(vec: Vec<T>) -> PrimitiveResult<Self> {
12 if vec.is_empty() {
13 return Err(PrimitiveError::Empty);
14 }
15 Ok(Self(vec))
16 }
17
18 pub fn from_one(item: T) -> Self {
20 Self(alloc::vec![item])
21 }
22
23 pub fn len(&self) -> usize {
25 self.0.len()
26 }
27
28 pub fn is_empty(&self) -> bool {
30 false
31 }
32
33 pub fn first(&self) -> &T {
35 &self.0[0]
36 }
37
38 pub fn last(&self) -> &T {
40 &self.0[self.0.len() - 1]
41 }
42
43 pub fn push(&mut self, item: T) {
45 self.0.push(item);
46 }
47
48 pub fn as_slice(&self) -> &[T] {
50 &self.0
51 }
52
53 pub fn into_inner(self) -> Vec<T> {
55 self.0
56 }
57
58 pub fn iter(&self) -> core::slice::Iter<'_, T> {
60 self.0.iter()
61 }
62}
63
64impl<T> Deref for NonEmptyVec<T> {
65 type Target = [T];
66
67 fn deref(&self) -> &Self::Target {
68 self.as_slice()
69 }
70}
71
72impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
73 type Error = PrimitiveError;
74
75 fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
76 Self::new(vec)
77 }
78}
79
80impl<T> From<NonEmptyVec<T>> for Vec<T> {
81 fn from(value: NonEmptyVec<T>) -> Self {
82 value.into_inner()
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use super::NonEmptyVec;
89 use crate::PrimitiveError;
90
91 #[test]
92 fn rejects_empty_vec() {
93 assert_eq!(
94 NonEmptyVec::<i32>::new(alloc::vec![]).unwrap_err(),
95 PrimitiveError::Empty
96 );
97 }
98
99 #[test]
100 fn accepts_non_empty_vec() {
101 let v = NonEmptyVec::new(alloc::vec![1, 2, 3]).unwrap();
102 assert_eq!(v.len(), 3);
103 assert!(!v.is_empty());
104 }
105
106 #[test]
107 fn from_one() {
108 let v = NonEmptyVec::from_one(42);
109 assert_eq!(v.first(), &42);
110 assert_eq!(v.last(), &42);
111 }
112
113 #[test]
114 fn first_and_last() {
115 let v = NonEmptyVec::new(alloc::vec![10, 20, 30]).unwrap();
116 assert_eq!(v.first(), &10);
117 assert_eq!(v.last(), &30);
118 }
119
120 #[test]
121 fn push_increases_len() {
122 let mut v = NonEmptyVec::from_one(1);
123 v.push(2);
124 assert_eq!(v.len(), 2);
125 }
126
127 #[test]
128 fn deref_to_slice() {
129 let v = NonEmptyVec::new(alloc::vec![1, 2, 3]).unwrap();
130 assert_eq!(&v[..], &[1, 2, 3]);
131 }
132
133 #[test]
134 fn into_inner() {
135 let v = NonEmptyVec::new(alloc::vec![1, 2]).unwrap();
136 assert_eq!(v.into_inner(), alloc::vec![1, 2]);
137 }
138
139 #[test]
140 fn try_from_vec() {
141 assert!(NonEmptyVec::<i32>::try_from(alloc::vec![]).is_err());
142 assert!(NonEmptyVec::try_from(alloc::vec![1]).is_ok());
143 }
144
145 #[test]
146 fn from_into_vec() {
147 let v = NonEmptyVec::from_one(99);
148 let inner: alloc::vec::Vec<i32> = alloc::vec::Vec::from(v);
149 assert_eq!(inner, alloc::vec![99]);
150 }
151
152 #[test]
153 fn iter() {
154 let v = NonEmptyVec::new(alloc::vec![1, 2, 3]).unwrap();
155 let sum: i32 = v.iter().sum();
156 assert_eq!(sum, 6);
157 }
158}