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}