circomspect_program_structure/utils/
nonempty_vec.rs1use anyhow::{anyhow, Error};
2use std::convert::TryFrom;
3use std::ops::{Index, IndexMut};
4
5#[derive(Clone, PartialEq, Eq)]
32pub struct NonEmptyVec<T> {
33 head: T,
34 tail: Vec<T>,
35}
36
37impl<T> NonEmptyVec<T> {
38 pub fn new(x: T) -> NonEmptyVec<T> {
39 NonEmptyVec { head: x, tail: Vec::new() }
40 }
41
42 pub fn first(&self) -> &T {
43 &self.head
44 }
45
46 pub fn first_mut(&mut self) -> &mut T {
47 &mut self.head
48 }
49
50 pub fn last(&self) -> &T {
52 match self.tail.last() {
53 Some(x) => x,
54 None => &self.head,
55 }
56 }
57
58 pub fn last_mut(&mut self) -> &mut T {
60 match self.tail.last_mut() {
61 Some(x) => x,
62 None => &mut self.head,
63 }
64 }
65
66 pub fn push(&mut self, x: T) {
68 self.tail.push(x);
69 }
70
71 pub fn pop(&mut self) -> Option<T> {
85 self.tail.pop()
86 }
87
88 pub fn len(&self) -> usize {
99 self.tail.len() + 1
100 }
101
102 pub fn is_empty(&self) -> bool {
104 false
105 }
106
107 pub fn iter(&self) -> NonEmptyIter<'_, T> {
109 NonEmptyIter::new(self)
110 }
111}
112
113impl<'a, T> IntoIterator for &'a NonEmptyVec<T> {
115 type Item = &'a T;
116 type IntoIter = NonEmptyIter<'a, T>;
117
118 fn into_iter(self) -> Self::IntoIter {
119 NonEmptyIter::new(self)
120 }
121}
122
123pub struct NonEmptyIter<'a, T> {
137 index: usize,
138 vec: &'a NonEmptyVec<T>,
139}
140
141impl<'a, T> NonEmptyIter<'a, T> {
142 fn new(vec: &'a NonEmptyVec<T>) -> NonEmptyIter<'a, T> {
143 NonEmptyIter { index: 0, vec }
144 }
145}
146
147impl<'a, T> Iterator for NonEmptyIter<'a, T> {
148 type Item = &'a T;
149
150 fn next(&mut self) -> Option<Self::Item> {
151 let x = if self.index == 0 {
152 Some(&self.vec.head)
153 } else {
154 self.vec.tail.get(self.index - 1)
156 };
157 self.index += 1;
158 x
159 }
160}
161
162impl<T> Index<usize> for NonEmptyVec<T> {
163 type Output = T;
164
165 fn index(&self, index: usize) -> &Self::Output {
166 match index {
167 0 => &self.head,
168 n => &self.tail[n - 1],
169 }
170 }
171}
172
173impl<T> Index<&usize> for NonEmptyVec<T> {
174 type Output = T;
175
176 fn index(&self, index: &usize) -> &Self::Output {
177 match index {
178 0 => &self.head,
179 n => &self.tail[n - 1],
180 }
181 }
182}
183
184impl<T> IndexMut<usize> for NonEmptyVec<T> {
185 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
186 match index {
187 0 => &mut self.head,
188 n => &mut self.tail[n - 1],
189 }
190 }
191}
192
193impl<T> IndexMut<&usize> for NonEmptyVec<T> {
194 fn index_mut(&mut self, index: &usize) -> &mut Self::Output {
195 match index {
196 0 => &mut self.head,
197 n => &mut self.tail[n - 1],
198 }
199 }
200}
201
202impl<T> From<NonEmptyVec<T>> for Vec<T> {
203 fn from(xs: NonEmptyVec<T>) -> Vec<T> {
204 let mut res = Vec::with_capacity(xs.len());
205 res.push(xs.head);
206 res.extend(xs.tail);
207 res
208 }
209}
210
211impl<T: Clone> From<&NonEmptyVec<T>> for Vec<T> {
212 fn from(xs: &NonEmptyVec<T>) -> Vec<T> {
213 xs.iter().cloned().collect()
214 }
215}
216
217impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
218 type Error = Error;
219
220 fn try_from(mut xs: Vec<T>) -> Result<NonEmptyVec<T>, Error> {
221 if let Some(x) = xs.pop() {
222 Ok(NonEmptyVec { head: x, tail: xs })
223 } else {
224 Err(anyhow!("cannot create a non-empty vector from an empty vector"))
225 }
226 }
227}
228
229impl<T: Clone> TryFrom<&Vec<T>> for NonEmptyVec<T> {
230 type Error = Error;
231
232 fn try_from(xs: &Vec<T>) -> Result<NonEmptyVec<T>, Error> {
233 if let Some(x) = xs.first() {
234 Ok(NonEmptyVec { head: x.clone(), tail: xs[1..].to_vec() })
235 } else {
236 Err(anyhow!("cannot create a non-empty vector from an empty vector"))
237 }
238 }
239}
240
241impl<T: Clone> TryFrom<&[T]> for NonEmptyVec<T> {
242 type Error = Error;
243
244 fn try_from(xs: &[T]) -> Result<NonEmptyVec<T>, Error> {
245 if let Some(x) = xs.first() {
246 Ok(NonEmptyVec { head: x.clone(), tail: xs[1..].to_vec() })
247 } else {
248 Err(anyhow!("cannot create a non-empty vector from an empty vector"))
249 }
250 }
251}
252
253impl<T: Clone, const N: usize> TryFrom<&[T; N]> for NonEmptyVec<T> {
254 type Error = Error;
255
256 fn try_from(xs: &[T; N]) -> Result<NonEmptyVec<T>, Error> {
257 if let Some(x) = xs.first() {
258 Ok(NonEmptyVec { head: x.clone(), tail: xs[1..].to_vec() })
259 } else {
260 Err(anyhow!("cannot create a non-empty vector from an empty vector"))
261 }
262 }
263}