embed_collections/
various.rs1use crate::seg_list::SegList;
53use core::fmt;
54
55pub struct Various<T> {
56 inner: VariousInner<T>,
57}
58
59enum VariousInner<T> {
60 One(Option<T>),
61 More(SegList<T>),
62}
63
64macro_rules! match_iter {
65 ($self: expr, $iter_type: tt, $f: tt $($m: tt)*) =>{
66 match $self.inner {
67 VariousInner::One($($m)* s)=>$iter_type::One(s.$f()),
68 VariousInner::More($($m)* s)=>$iter_type::More(s.$f()),
69 }
70 }
71}
72
73macro_rules! match_call {
74 ($self: expr, $cls: tt, $call: tt) => {
75 match $self {
76 $cls::One(i) => i.$call(),
77 $cls::More(i) => i.$call(),
78 }
79 };
80}
81
82impl<T> Default for Various<T> {
83 fn default() -> Self {
84 Self::new()
85 }
86}
87
88impl<T> Various<T> {
89 #[inline]
90 pub fn new() -> Self {
91 Self { inner: VariousInner::One(None) }
92 }
93
94 #[inline]
95 pub fn from(item: T) -> Self {
96 Self { inner: VariousInner::One(Some(item)) }
97 }
98
99 #[inline]
100 pub fn is_empty(&self) -> bool {
101 match &self.inner {
102 VariousInner::One(i) => i.is_none(),
103 VariousInner::More(i) => i.is_empty(),
104 }
105 }
106
107 #[inline]
108 pub fn len(&self) -> usize {
109 match &self.inner {
110 VariousInner::One(i) => {
111 if i.is_none() {
112 0
113 } else {
114 1
115 }
116 }
117 VariousInner::More(i) => i.len(),
118 }
119 }
120
121 #[inline]
123 pub fn push(&mut self, new_item: T) {
124 match self.inner {
125 VariousInner::More(ref mut s) => {
126 s.push(new_item);
127 }
128 VariousInner::One(ref mut s) => {
129 if s.is_none() {
130 s.replace(new_item);
131 } else {
132 let mut l = SegList::new();
133 l.push(s.take().unwrap());
134 l.push(new_item);
135 self.inner = VariousInner::More(l);
136 }
137 }
138 }
139 }
140
141 #[inline]
143 pub fn pop(&mut self) -> Option<T> {
144 match self.inner {
145 VariousInner::More(ref mut s) => s.pop(),
146 VariousInner::One(ref mut s) => s.take(),
147 }
148 }
149
150 #[inline]
151 pub fn iter<'a>(&'a self) -> VariousIter<'a, T> {
152 match_iter!(self, VariousIter, iter ref)
153 }
154
155 pub fn iter_mut<'a>(&'a mut self) -> VariousIterMut<'a, T> {
156 match_iter!(self, VariousIterMut, iter_mut ref mut)
157 }
158
159 #[inline]
160 pub fn first(&self) -> Option<&T> {
161 match self.inner {
162 VariousInner::One(ref s) => s.as_ref(),
163 VariousInner::More(ref s) => s.iter().next(),
164 }
165 }
166
167 #[inline]
168 pub fn last(&self) -> Option<&T> {
169 match self.inner {
170 VariousInner::More(ref s) => s.last(),
171 VariousInner::One(ref s) => s.as_ref(),
172 }
173 }
174
175 pub fn last_mut(&mut self) -> Option<&mut T> {
176 match self.inner {
177 VariousInner::More(ref mut s) => s.last_mut(),
178 VariousInner::One(ref mut s) => s.as_mut(),
179 }
180 }
181
182 #[inline]
184 pub fn take(&mut self) -> Self {
185 use core::mem;
186 Various { inner: mem::replace(&mut self.inner, VariousInner::One(None)) }
187 }
188
189 #[inline]
191 pub fn clear(&mut self) {
192 match &mut self.inner {
193 VariousInner::One(inner) => {
194 let _ = inner.take();
195 }
196 VariousInner::More(inner) => inner.clear(),
197 }
198 }
199}
200
201impl<T> IntoIterator for Various<T> {
202 type Item = T;
203
204 type IntoIter = VariousIntoIter<T>;
205
206 fn into_iter(self) -> VariousIntoIter<T> {
207 match_iter!(self, VariousIntoIter, into_iter)
208 }
209}
210
211impl<'a, T> IntoIterator for &'a Various<T> {
212 type Item = &'a T;
213
214 type IntoIter = VariousIter<'a, T>;
215
216 fn into_iter(self) -> VariousIter<'a, T> {
217 match_iter!(self, VariousIter, iter ref)
218 }
219}
220
221pub enum VariousIter<'a, T> {
222 One(core::option::Iter<'a, T>),
223 More(crate::seg_list::SegListIter<'a, T>),
224}
225
226impl<'a, T> core::iter::Iterator for VariousIter<'a, T> {
227 type Item = &'a T;
228
229 fn next(&mut self) -> Option<Self::Item> {
230 match_call!(self, VariousIter, next)
231 }
232}
233
234pub enum VariousIterMut<'a, T> {
235 One(core::option::IterMut<'a, T>),
236 More(crate::seg_list::SegListIterMut<'a, T>),
237}
238
239impl<'a, T> core::iter::Iterator for VariousIterMut<'a, T> {
240 type Item = &'a mut T;
241
242 fn next(&mut self) -> Option<Self::Item> {
243 match_call!(self, VariousIterMut, next)
244 }
245}
246
247pub enum VariousIntoIter<T> {
248 One(core::option::IntoIter<T>),
249 More(crate::seg_list::SegListDrain<T>),
250}
251
252impl<T> core::iter::Iterator for VariousIntoIter<T> {
253 type Item = T;
254
255 fn next(&mut self) -> Option<Self::Item> {
256 match_call!(self, VariousIntoIter, next)
257 }
258}
259
260impl<T: fmt::Debug> fmt::Debug for Various<T> {
261 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
262 match &self.inner {
263 VariousInner::One(s) => s.fmt(f),
264 VariousInner::More(s) => s.fmt(f),
265 }
266 }
267}
268
269#[cfg(test)]
270mod tests {
271
272 use super::*;
273
274 #[test]
275 fn test_one() {
276 let mut s = Various::new();
277 s.push(1);
278 assert_eq!(s.len(), 1);
279 for i in &s {
280 assert_eq!(*i, 1);
281 }
282 assert_eq!(Some(1), s.pop());
283 assert_eq!(s.len(), 0);
284 if (&s).into_iter().next().is_some() {
285 unreachable!();
286 }
287 }
288
289 #[test]
290 fn test_cap_0() {
291 let mut s = Various::new();
292 s.push(1);
293 assert_eq!(s.len(), 1);
294 for i in &s {
295 assert_eq!(*i, 1);
296 }
297 s.push(2);
298 s.push(3);
299 assert_eq!(s.len(), 3);
300 let mut total = 0;
301 for i in &s {
302 total += *i;
303 }
304 assert_eq!(total, 6);
305 for i in s.iter_mut() {
306 *i += 1;
307 }
308 let mut total = 0;
309 for i in &s {
310 total += *i;
311 }
312 assert_eq!(total, 9);
313 assert_eq!(s.pop(), Some(4));
314 let mut total = 0;
315 for i in s {
316 total += i;
317 }
318 assert_eq!(total, 5);
319 }
320
321 #[test]
322 fn test_more() {
323 let mut s = Various::new();
324 s.push(1);
325 s.push(2);
326 s.push(3);
327 assert_eq!(s.len(), 3);
328 let mut total = 0;
329 for i in &s {
330 total += *i;
331 }
332 assert_eq!(total, 6);
333 for i in s.iter_mut() {
334 *i += 1;
335 }
336 let mut total = 0;
337 for i in &s {
338 total += *i;
339 }
340 assert_eq!(total, 9);
341 assert_eq!(s.pop(), Some(4));
342 let mut total = 0;
343 for i in s {
344 total += i;
345 }
346 assert_eq!(total, 5);
347 }
348}