embed_collections/
various.rs1use crate::seg_list::SegList;
2use core::fmt;
3
4pub struct Various<T> {
5 inner: VariousInner<T>,
6}
7
8enum VariousInner<T> {
9 One(Option<T>),
10 More(SegList<T>),
11}
12
13macro_rules! match_iter {
14 ($self: expr, $iter_type: tt, $f: tt $($m: tt)*) =>{
15 match $self.inner {
16 VariousInner::One($($m)* s)=>$iter_type::One(s.$f()),
17 VariousInner::More($($m)* s)=>$iter_type::More(s.$f()),
18 }
19 }
20}
21
22macro_rules! match_call {
23 ($self: expr, $cls: tt, $call: tt) => {
24 match $self {
25 $cls::One(i) => i.$call(),
26 $cls::More(i) => i.$call(),
27 }
28 };
29}
30
31impl<T> Default for Various<T> {
32 fn default() -> Self {
33 Self::new()
34 }
35}
36
37impl<T> Various<T> {
38 #[inline]
39 pub fn new() -> Self {
40 Self { inner: VariousInner::One(None) }
41 }
42
43 #[inline]
44 pub fn from(item: T) -> Self {
45 Self { inner: VariousInner::One(Some(item)) }
46 }
47
48 #[inline]
49 pub fn is_empty(&self) -> bool {
50 match &self.inner {
51 VariousInner::One(i) => i.is_none(),
52 VariousInner::More(i) => i.is_empty(),
53 }
54 }
55
56 #[inline]
57 pub fn len(&self) -> usize {
58 match &self.inner {
59 VariousInner::One(i) => {
60 if i.is_none() {
61 return 0;
62 } else {
63 return 1;
64 }
65 }
66 VariousInner::More(i) => i.len(),
67 }
68 }
69
70 #[inline]
72 pub fn push(&mut self, new_item: T) {
73 match self.inner {
74 VariousInner::More(ref mut s) => {
75 s.push(new_item);
76 }
77 VariousInner::One(ref mut s) => {
78 if s.is_none() {
79 s.replace(new_item);
80 } else {
81 let mut l = SegList::new();
82 l.push(s.take().unwrap());
83 l.push(new_item);
84 self.inner = VariousInner::More(l);
85 }
86 }
87 }
88 }
89
90 #[inline]
92 pub fn pop(&mut self) -> Option<T> {
93 match self.inner {
94 VariousInner::More(ref mut s) => s.pop(),
95 VariousInner::One(ref mut s) => s.take(),
96 }
97 }
98
99 #[inline]
100 pub fn iter<'a>(&'a self) -> VariousIter<'a, T> {
101 match_iter!(self, VariousIter, iter ref)
102 }
103
104 pub fn iter_mut<'a>(&'a mut self) -> VariousIterMut<'a, T> {
105 match_iter!(self, VariousIterMut, iter_mut ref mut)
106 }
107
108 #[inline]
109 pub fn first(&self) -> Option<&T> {
110 match self.inner {
111 VariousInner::One(ref s) => s.as_ref(),
112 VariousInner::More(ref s) => s.iter().next(),
113 }
114 }
115
116 #[inline]
117 pub fn last(&self) -> Option<&T> {
118 match self.inner {
119 VariousInner::More(ref s) => s.last(),
120 VariousInner::One(ref s) => s.as_ref(),
121 }
122 }
123
124 pub fn last_mut(&mut self) -> Option<&mut T> {
125 match self.inner {
126 VariousInner::More(ref mut s) => s.last_mut(),
127 VariousInner::One(ref mut s) => s.as_mut(),
128 }
129 }
130
131 #[inline]
132 pub fn take(&mut self) -> Self {
133 use core::mem;
134 Various { inner: mem::replace(&mut self.inner, VariousInner::One(None)) }
135 }
136}
137
138impl<T> IntoIterator for Various<T> {
139 type Item = T;
140
141 type IntoIter = VariousIntoIter<T>;
142
143 fn into_iter(self) -> VariousIntoIter<T> {
144 match_iter!(self, VariousIntoIter, into_iter)
145 }
146}
147
148impl<'a, T> IntoIterator for &'a Various<T> {
149 type Item = &'a T;
150
151 type IntoIter = VariousIter<'a, T>;
152
153 fn into_iter(self) -> VariousIter<'a, T> {
154 match_iter!(self, VariousIter, iter ref)
155 }
156}
157
158pub enum VariousIter<'a, T> {
159 One(core::option::Iter<'a, T>),
160 More(crate::seg_list::SegListIter<'a, T>),
161}
162
163impl<'a, T> core::iter::Iterator for VariousIter<'a, T> {
164 type Item = &'a T;
165
166 fn next(&mut self) -> Option<Self::Item> {
167 match_call!(self, VariousIter, next)
168 }
169}
170
171pub enum VariousIterMut<'a, T> {
172 One(core::option::IterMut<'a, T>),
173 More(crate::seg_list::SegListIterMut<'a, T>),
174}
175
176impl<'a, T> core::iter::Iterator for VariousIterMut<'a, T> {
177 type Item = &'a mut T;
178
179 fn next(&mut self) -> Option<Self::Item> {
180 match_call!(self, VariousIterMut, next)
181 }
182}
183
184pub enum VariousIntoIter<T> {
185 One(core::option::IntoIter<T>),
186 More(crate::seg_list::SegListDrain<T>),
187}
188
189impl<T> core::iter::Iterator for VariousIntoIter<T> {
190 type Item = T;
191
192 fn next(&mut self) -> Option<Self::Item> {
193 match_call!(self, VariousIntoIter, next)
194 }
195}
196
197impl<T: fmt::Debug> fmt::Debug for Various<T> {
198 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
199 match &self.inner {
200 VariousInner::One(s) => s.fmt(f),
201 VariousInner::More(s) => s.fmt(f),
202 }
203 }
204}
205
206#[cfg(test)]
207mod tests {
208
209 use super::*;
210
211 #[test]
212 fn test_one() {
213 let mut s = Various::new();
214 s.push(1);
215 assert_eq!(s.len(), 1);
216 for i in &s {
217 assert_eq!(*i, 1);
218 }
219 assert_eq!(Some(1), s.pop());
220 assert_eq!(s.len(), 0);
221 if (&s).into_iter().next().is_some() {
222 unreachable!();
223 }
224 }
225
226 #[test]
227 fn test_cap_0() {
228 let mut s = Various::new();
229 s.push(1);
230 assert_eq!(s.len(), 1);
231 for i in &s {
232 assert_eq!(*i, 1);
233 }
234 s.push(2);
235 s.push(3);
236 assert_eq!(s.len(), 3);
237 let mut total = 0;
238 for i in &s {
239 total += *i;
240 }
241 assert_eq!(total, 6);
242 for i in s.iter_mut() {
243 *i += 1;
244 }
245 let mut total = 0;
246 for i in &s {
247 total += *i;
248 }
249 assert_eq!(total, 9);
250 assert_eq!(s.pop(), Some(4));
251 let mut total = 0;
252 for i in s {
253 total += i;
254 }
255 assert_eq!(total, 5);
256 }
257
258 #[test]
259 fn test_more() {
260 let mut s = Various::new();
261 s.push(1);
262 s.push(2);
263 s.push(3);
264 assert_eq!(s.len(), 3);
265 let mut total = 0;
266 for i in &s {
267 total += *i;
268 }
269 assert_eq!(total, 6);
270 for i in s.iter_mut() {
271 *i += 1;
272 }
273 let mut total = 0;
274 for i in &s {
275 total += *i;
276 }
277 assert_eq!(total, 9);
278 assert_eq!(s.pop(), Some(4));
279 let mut total = 0;
280 for i in s {
281 total += i;
282 }
283 assert_eq!(total, 5);
284 }
285}