texcraft_stdext/collections/
nevec.rs1use std::ops::Index;
8
9#[derive(Debug, Default, Clone)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct Nevec<T> {
13 first: T,
14 tail: Vec<T>,
15}
16
17impl<T> Nevec<T> {
18 pub fn new(first: T) -> Nevec<T> {
20 Nevec::<T>::new_with_tail(first, Vec::new())
21 }
22
23 pub fn with_capacity(first: T, capacity: usize) -> Nevec<T> {
25 Nevec::<T>::new_with_tail(first, Vec::with_capacity(capacity))
26 }
27
28 pub fn new_with_tail(first: T, tail: Vec<T>) -> Nevec<T> {
30 Nevec { first, tail }
31 }
32
33 pub fn last(&self) -> &T {
36 match self.tail.last() {
37 None => &self.first,
38 Some(t) => t,
39 }
40 }
41
42 pub fn last_mut(&mut self) -> &mut T {
45 match self.tail.last_mut() {
46 None => &mut self.first,
47 Some(t) => t,
48 }
49 }
50
51 pub fn push(&mut self, t: T) {
53 self.tail.push(t)
54 }
55
56 pub fn pop(mut self) -> T {
66 match self.tail.pop() {
67 None => self.first,
68 Some(t) => t,
69 }
70 }
71
72 pub fn pop_from_tail(&mut self) -> Option<T> {
78 self.tail.pop()
79 }
80
81 pub fn len(&self) -> usize {
83 1 + self.tail.len()
84 }
85
86 pub fn is_empty(&self) -> bool {
88 true
89 }
90
91 pub fn get(&self, i: usize) -> Option<&T> {
93 if i == 0 {
94 return Some(&self.first);
95 }
96 self.tail.get(i - 1)
97 }
98
99 pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
101 if i == 0 {
102 return Some(&mut self.first);
103 }
104 self.tail.get_mut(i - 1)
105 }
106}
107
108impl<T> Index<usize> for Nevec<T> {
109 type Output = T;
110
111 fn index(&self, i: usize) -> &Self::Output {
112 if i == 0 {
113 &self.first
114 } else {
115 &self.tail[i - 1]
116 }
117 }
118}
119
120impl<'a, T> IntoIterator for &'a Nevec<T> {
121 type Item = &'a T;
122 type IntoIter = NevecIter<'a, T>;
123
124 fn into_iter(self) -> NevecIter<'a, T> {
125 NevecIter { vec: self, i: 0 }
126 }
127}
128
129impl<T: std::fmt::Display> std::fmt::Display for Nevec<T> {
130 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
131 for t in self {
132 write![f, "{t}"]?;
133 }
134 Ok(())
135 }
136}
137
138pub struct NevecIter<'a, T> {
139 vec: &'a Nevec<T>,
140 i: usize,
141}
142
143impl<'a, T> Iterator for NevecIter<'a, T> {
144 type Item = &'a T;
145 fn next(&mut self) -> Option<Self::Item> {
146 if self.i >= self.vec.len() {
147 None
148 } else {
149 self.i += 1;
150 Some(&self.vec[self.i - 1])
151 }
152 }
153}
154
155#[macro_export]
157macro_rules! nevec {
158 ( $first: expr, $ ( $ x : expr ) , * ) => (
159 Nevec::new_with_tail($first, vec![$ ( $ x ) , *])
160 );
161 ( $first: expr, $ ( $ x : expr , ) * ) => ( nevec ! [ $first, $ ( $ x ) , * ] );
162 ( $first: expr ) => {
163 Nevec::new($first)
164 };
165}
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170
171 #[test]
172 fn singleton_vector() {
173 let mut v = nevec![3];
174 assert_eq![v.len(), 1];
175 assert_eq![v.last(), &3];
176 assert_eq![v.last_mut(), &3];
177 assert_eq![v.pop_from_tail(), None];
178 assert_eq![v.pop(), 3];
179 }
180
181 #[test]
182 fn two_element_vector() {
183 let mut v = nevec![3, 4];
184 assert_eq![v.len(), 2];
185 assert_eq![v.last(), &4];
186 assert_eq![v.last_mut(), &4];
187 assert_eq![v[0], 3];
188 assert_eq![v[1], 4];
189 assert_eq![v.pop_from_tail(), Some(4)];
190 assert_eq![v.last(), &3];
191 assert_eq![v.last_mut(), &3];
192 assert_eq![v.pop_from_tail(), None];
193 }
194
195 #[test]
196 fn vector_with_push() {
197 let mut v = nevec![3, 4,];
198 assert_eq![v.len(), 2];
199 v.push(5);
200 assert_eq![v.len(), 3];
201 assert_eq![v.last(), &5];
202 assert_eq![v.last_mut(), &5];
203 assert_eq![v.pop_from_tail(), Some(5)];
204 }
205
206 #[test]
207 fn other_macro_constructor_case() {
208 let mut v = nevec![3,];
209 assert_eq![v.len(), 1];
210 assert_eq![v.last(), &3];
211 assert_eq![v.last_mut(), &3];
212 assert_eq![v.pop_from_tail(), None];
213 assert_eq![v.pop(), 3];
214 }
215}