1use std::{
5 cmp::Ordering,
6 collections::vec_deque::{self, VecDeque},
7 fmt,
8 iter::{IntoIterator, once},
9 mem::{swap, take},
10 ops::{Index, IndexMut},
11};
12
13#[macro_export]
14macro_rules! ziplist {
15 ([$($up:expr),*], $focus:expr, [$($down:expr),*]) => { $crate::ziplist::ZipList::new([$($up),*], $focus, [$($down),*]) };
16 ([$($up:expr),*], $focus:expr) => { $crate::ziplist::ZipList::new([$($up),*], $focus, []) };
17 ($focus:expr, [$($down:expr),*]) => { $crate::ziplist::ZipList::new([], $focus, [$($down),*]) };
18 ($focus:expr, $($down:expr),+) => { $crate::ziplist::ZipList::new([], $focus, [$($down),*]) };
19 ($focus:expr) => { $crate::ziplist::ZipList::new([], $focus, []) };
20}
21
22macro_rules! pop_where {
23 ($self:ident, $lst:ident, $($pred:tt)+) => {{
24 let placeholder = ::std::mem::take(&mut $self.$lst);
25 let mut remaining = ::std::collections::VecDeque::default();
26 let mut popped = None;
27 #[allow(unused_mut)]
28 let mut pred = $($pred)+;
29
30 for item in placeholder.into_iter() {
31 if pred(&item) {
32 popped = Some(item);
33 } else {
34 remaining.push_back(item);
35 }
36 }
37
38 ::std::mem::swap(&mut $self.$lst, &mut remaining);
39
40 popped
41 }};
42}
43
44#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
46pub enum Position {
47 #[default]
49 Focus,
50 Before,
52 After,
54 Head,
56 Tail,
58}
59
60#[derive(Debug, Default, Clone, PartialEq, Eq)]
71pub struct ZipList<T> {
72 pub(crate) up: VecDeque<T>,
73 pub(crate) focus: T,
74 pub(crate) down: VecDeque<T>,
75}
76
77impl<T: fmt::Display> fmt::Display for ZipList<T> {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 let up: Vec<String> = self.up.iter().rev().map(|t| t.to_string()).collect();
80 let down: Vec<String> = self.down.iter().map(|t| t.to_string()).collect();
81
82 write!(
83 f,
84 "ZipList([{}], {}, [{}])",
85 up.join(", "),
86 self.focus,
87 down.join(", ")
88 )
89 }
90}
91
92impl<T> ZipList<T> {
93 pub fn new<I, J>(up: I, focus: T, down: J) -> Self
96 where
97 I: IntoIterator<Item = T>,
98 J: IntoIterator<Item = T>,
99 {
100 let mut reversed_up = VecDeque::new();
101 for elem in up.into_iter() {
102 reversed_up.push_front(elem);
103 }
104
105 Self {
106 focus,
107 up: reversed_up,
108 down: down.into_iter().collect(),
109 }
110 }
111
112 pub fn try_from_iter<I>(iter: I) -> Option<Self>
117 where
118 I: IntoIterator<Item = T>,
119 {
120 let mut it = iter.into_iter();
121 let focus = it.next()?;
122
123 Some(Self {
124 up: VecDeque::default(),
125 focus,
126 down: it.collect(),
127 })
128 }
129
130 pub fn len(&self) -> usize {
132 self.up.len() + self.down.len() + 1
133 }
134
135 pub fn is_empty(&self) -> bool {
137 false
138 }
139
140 pub fn iter(&self) -> Iter<'_, T> {
143 Iter {
144 up: self.up.iter(),
145 focus: Some(&self.focus),
146 down: self.down.iter(),
147 }
148 }
149
150 pub fn iter_mut(&mut self) -> IterMut<'_, T> {
153 IterMut {
154 up: self.up.iter_mut(),
155 focus: Some(&mut self.focus),
156 down: self.down.iter_mut(),
157 }
158 }
159
160 pub fn unravel(&self) -> impl Iterator<Item = &T> {
163 once(&self.focus)
164 .chain(self.down.iter())
165 .chain(self.up.iter().rev())
166 }
167
168 pub fn flatten(self) -> Vec<T> {
171 self.into_iter().map(|(_, t)| t).collect()
172 }
173
174 pub fn head(&self) -> &T {
176 self.up.back().unwrap_or(&self.focus)
177 }
178
179 pub fn focused(&self) -> &T {
181 &self.focus
182 }
183
184 pub fn last(&self) -> &T {
186 self.down.back().unwrap_or(&self.focus)
187 }
188
189 pub fn last_mut(&mut self) -> &mut T {
190 self.down.back_mut().unwrap_or(&mut self.focus)
191 }
192
193 pub fn swap_focus_and_head(&mut self) -> &mut Self {
196 let mut tmp = take(&mut self.up);
197
198 if let Some(head) = tmp.pop_back() {
199 self.down.push_front(head);
200 }
201
202 for item in tmp.into_iter() {
203 self.down.push_front(item);
204 }
205
206 self
207 }
208
209 pub fn rotate_focus_to_head(&mut self) -> &mut Self {
211 self.down.extend(self.up.drain(..).rev());
212
213 self
214 }
215
216 pub fn focus_head(&mut self) -> &mut Self {
218 let mut head = match self.up.pop_back() {
219 None => return self, Some(t) => t,
221 };
222
223 swap(&mut head, &mut self.focus);
224 self.down.push_front(head);
225
226 for item in take(&mut self.up).into_iter() {
227 self.down.push_front(item);
228 }
229
230 self
231 }
232
233 pub fn focus_tail(&mut self) -> &mut Self {
235 let mut tail = match self.down.pop_back() {
236 None => return self, Some(t) => t,
238 };
239
240 swap(&mut tail, &mut self.focus);
241 self.up.push_front(tail);
242
243 for item in take(&mut self.down).into_iter() {
244 self.up.push_front(item);
245 }
246
247 self
248 }
249
250 pub fn insert(&mut self, t: T) -> &mut Self {
253 self.insert_at(Position::default(), t)
254 }
255
256 pub fn insert_at(&mut self, pos: Position, mut t: T) -> &mut Self {
261 use Position::*;
262
263 match pos {
264 Focus => {
265 self.swap_focus(&mut t);
266 self.down.push_front(t);
267 }
268 Before => self.up.push_front(t),
269 After => self.down.push_front(t),
270 Head => self.up.push_back(t),
271 Tail => self.down.push_back(t),
272 };
273
274 self
275 }
276
277 pub fn remove_focused(mut self) -> (T, Option<Self>) {
280 let focus = match self.down.pop_front().or_else(|| self.up.pop_front()) {
281 Some(focus) => focus,
282 None => return (self.focus, None),
283 };
284
285 (
286 self.focus,
287 Some(Self {
288 focus,
289 up: self.up,
290 down: self.down,
291 }),
292 )
293 }
294
295 pub fn remove_focused_unchecked(&mut self) -> T {
300 let mut focus = self
301 .down
302 .pop_front()
303 .or_else(|| self.up.pop_front())
304 .expect("Ziplist only contained a single element");
305 swap(&mut focus, &mut self.focus);
306
307 focus
308 }
309
310 pub fn remove_where_with_default(
314 &mut self,
315 mut pred: impl FnMut(&T) -> bool,
316 mut default: impl FnMut() -> T,
317 ) -> Option<T> {
318 if let Some(found) = pop_where!(self, up, |elem: &T| pred(elem)) {
319 return Some(found);
320 } else if let Some(found) = pop_where!(self, down, |elem: &T| pred(elem)) {
321 return Some(found);
322 }
323
324 if pred(&self.focus) {
325 let mut focus = match self.down.pop_front().or_else(|| self.up.pop_front()) {
326 Some(focus) => focus,
327 None => default(),
328 };
329 swap(&mut focus, &mut self.focus);
330
331 Some(focus)
332 } else {
333 None
334 }
335 }
336
337 pub fn map<F, U>(self, mut f: F) -> ZipList<U>
339 where
340 F: FnMut(T) -> U,
341 {
342 ZipList {
343 focus: f(self.focus),
344 up: self.up.into_iter().map(&mut f).collect(),
345 down: self.down.into_iter().map(&mut f).collect(),
346 }
347 }
348
349 pub fn filter<F>(self, mut f: F) -> Option<Self>
355 where
356 F: FnMut(&T) -> bool,
357 {
358 let new_stack = Self {
359 focus: self.focus,
360 up: self.up.into_iter().filter(&mut f).collect(),
361 down: self.down.into_iter().filter(&mut f).collect(),
362 };
363
364 if f(&new_stack.focus) {
365 Some(new_stack)
366 } else {
367 let (_, maybe_stack) = new_stack.remove_focused();
368 maybe_stack
369 }
370 }
371
372 pub fn filter_unchecked<F>(&mut self, mut f: F)
373 where
374 F: FnMut(&T) -> bool,
375 {
376 self.up.retain(&mut f);
377 self.down.retain(&mut f);
378
379 if !f(&self.focus) {
380 self.remove_focused_unchecked();
381 }
382 }
383
384 #[inline]
387 pub fn reverse(&mut self) -> &mut Self {
388 swap(&mut self.up, &mut self.down);
389
390 self
391 }
392
393 #[inline]
394 pub(crate) fn swap_focus(&mut self, new: &mut T) {
395 swap(&mut self.focus, new);
396 }
397
398 #[inline]
399 fn rev_up(&mut self) -> &mut Self {
400 let mut reversed = take(&mut self.up).into_iter().rev().collect();
401 swap(&mut self.up, &mut reversed);
402
403 self
404 }
405
406 #[inline]
407 fn rev_down(&mut self) -> &mut Self {
408 let mut reversed = take(&mut self.down).into_iter().rev().collect();
409 swap(&mut self.down, &mut reversed);
410
411 self
412 }
413
414 pub fn focus_up(&mut self) -> &mut Self {
417 match (self.up.is_empty(), self.down.is_empty()) {
418 (false, _) => {
421 let mut focus = self.up.pop_front().expect("non-empty");
422 self.swap_focus(&mut focus);
423 self.down.push_front(focus);
424 }
425
426 (true, false) => {
428 let mut focus = self.down.pop_back().expect("non-empty");
429 self.swap_focus(&mut focus);
430 self.down.push_front(focus);
431 self.reverse().rev_up();
432 }
433
434 (true, true) => (),
436 }
437
438 self
439 }
440
441 pub fn focus_down(&mut self) -> &mut Self {
444 match (self.up.is_empty(), self.down.is_empty()) {
445 (_, false) => {
448 let mut focus = self.down.pop_front().expect("non-empty");
449 self.swap_focus(&mut focus);
450 self.up.push_front(focus);
451 }
452
453 (false, true) => {
455 let mut focus = self.up.pop_back().expect("non-empty");
456 self.swap_focus(&mut focus);
457 self.up.push_front(focus);
458 self.reverse().rev_down();
459 }
460
461 (true, true) => (),
463 }
464
465 self
466 }
467
468 pub fn focus_element_by<F>(&mut self, mut f: F) -> bool
473 where
474 F: FnMut(&T) -> bool,
475 {
476 for _ in 0..self.len() {
477 if f(&self.focus) {
478 return true;
479 }
480 self.focus_down();
481 }
482
483 false
484 }
485
486 pub fn focus_element_by_mut<F>(&mut self, mut f: F) -> bool
491 where
492 F: FnMut(&mut T) -> bool,
493 {
494 for _ in 0..self.len() {
495 if f(&mut self.focus) {
496 return true;
497 }
498 self.focus_down();
499 }
500
501 false
502 }
503
504 pub fn swap_up(&mut self) -> &mut Self {
507 match self.up.pop_front() {
508 Some(t) => {
509 self.down.push_front(t);
510 self
511 }
512 None => self.reverse().rev_up(),
513 }
514 }
515
516 pub fn swap_down(&mut self) -> &mut Self {
519 match self.down.pop_front() {
520 Some(t) => {
521 self.up.push_front(t);
522 self
523 }
524 None => self.reverse().rev_down(),
525 }
526 }
527
528 pub fn rotate_up(&mut self) -> &mut Self {
531 match self.up.pop_back() {
532 Some(t) => {
533 self.down.push_back(t);
534 self
535 }
536 None => self.reverse().rev_up(),
537 }
538 }
539
540 pub fn rotate_down(&mut self) -> &mut Self {
543 match self.down.pop_back() {
544 Some(t) => {
545 self.up.push_back(t);
546 self
547 }
548 None => self.reverse().rev_down(),
549 }
550 }
551}
552
553impl<T: Clone> ZipList<T> {
554 pub fn extract<F>(&self, mut f: F) -> (Option<Self>, Vec<T>)
557 where
558 F: FnMut(&T) -> bool,
559 {
560 let mut extracted = Vec::new();
561 let mut new_stack = Self {
562 focus: self.focus.clone(),
563 up: Default::default(),
564 down: Default::default(),
565 };
566
567 for t in self.up.clone().into_iter().rev() {
568 if f(&t) {
569 new_stack.up.push_front(t);
570 } else {
571 extracted.push(t);
572 }
573 }
574
575 let up_to_focus = extracted.len();
576
577 for t in self.down.clone().into_iter() {
578 if f(&t) {
579 new_stack.down.push_back(t);
580 } else {
581 extracted.push(t);
582 }
583 }
584
585 if f(&new_stack.focus) {
586 return (Some(new_stack), extracted);
587 }
588
589 let (t, maybe_stack) = new_stack.remove_focused();
590 extracted.insert(up_to_focus, t);
591
592 (maybe_stack, extracted)
593 }
594}
595
596impl<T: PartialEq> ZipList<T> {
597 pub fn contains(&self, t: &T) -> bool {
599 &self.focus == t || self.up.contains(t) || self.down.contains(t)
600 }
601
602 pub fn focus_element(&mut self, t: &T) {
607 self.focus_element_by(|elem| elem == t);
608 }
609
610 pub fn remove(mut self, t: &T) -> (Option<T>, Option<Self>) {
616 if let Some(found) = pop_where!(self, up, |elem: &T| elem == t) {
617 return (Some(found), Some(self));
618 }
619
620 if let Some(found) = pop_where!(self, down, |elem: &T| elem == t) {
621 return (Some(found), Some(self));
622 }
623
624 if t == &self.focus {
625 let (focus, stack) = self.remove_focused();
626 (Some(focus), stack)
627 } else {
628 (None, Some(self))
629 }
630 }
631}
632
633impl<T> Index<usize> for ZipList<T> {
634 type Output = T;
635
636 fn index(&self, i: usize) -> &Self::Output {
637 let nup = self.up.len();
638 match i.cmp(&nup) {
639 Ordering::Less => &self.up[nup - i - 1],
640 Ordering::Equal => &self.focus,
641 Ordering::Greater => &self.down[i - nup - 1],
642 }
643 }
644}
645
646impl<T> IndexMut<usize> for ZipList<T> {
647 fn index_mut(&mut self, i: usize) -> &mut Self::Output {
648 let nup = self.up.len();
649 match i.cmp(&nup) {
650 Ordering::Less => &mut self.up[nup - i - 1],
651 Ordering::Equal => &mut self.focus,
652 Ordering::Greater => &mut self.down[i - nup - 1],
653 }
654 }
655}
656
657#[derive(Debug)]
661pub struct IntoIter<T> {
662 up: VecDeque<T>,
663 focus: Option<T>,
664 down: VecDeque<T>,
665}
666
667impl<T> Iterator for IntoIter<T> {
668 type Item = (bool, T);
669
670 fn next(&mut self) -> Option<Self::Item> {
671 self.up
672 .pop_back()
673 .map(|t| (false, t))
674 .or_else(|| self.focus.take().map(|t| (true, t)))
675 .or_else(|| self.down.pop_front().map(|t| (false, t)))
676 }
677}
678
679impl<T> IntoIterator for ZipList<T> {
680 type Item = (bool, T);
681 type IntoIter = IntoIter<T>;
682
683 fn into_iter(self) -> IntoIter<T> {
684 IntoIter {
685 up: self.up,
686 focus: Some(self.focus),
687 down: self.down,
688 }
689 }
690}
691
692#[derive(Debug)]
694pub struct Iter<'a, T> {
695 up: vec_deque::Iter<'a, T>,
696 focus: Option<&'a T>,
697 down: vec_deque::Iter<'a, T>,
698}
699
700impl<'a, T> Iterator for Iter<'a, T> {
701 type Item = (bool, &'a T);
702
703 fn next(&mut self) -> Option<Self::Item> {
704 self.up
705 .next_back()
706 .map(|t| (false, t))
707 .or_else(|| self.focus.take().map(|t| (true, t)))
708 .or_else(|| self.down.next().map(|t| (false, t)))
709 }
710}
711
712impl<'a, T> IntoIterator for &'a ZipList<T> {
713 type Item = (bool, &'a T);
714 type IntoIter = Iter<'a, T>;
715
716 fn into_iter(self) -> Iter<'a, T> {
717 self.iter()
718 }
719}
720
721#[derive(Debug)]
723pub struct IterMut<'a, T> {
724 up: vec_deque::IterMut<'a, T>,
725 focus: Option<&'a mut T>,
726 down: vec_deque::IterMut<'a, T>,
727}
728
729impl<'a, T> Iterator for IterMut<'a, T> {
730 type Item = (bool, &'a mut T);
731
732 fn next(&mut self) -> Option<Self::Item> {
733 self.up
734 .next_back()
735 .map(|t| (false, t))
736 .or_else(|| self.focus.take().map(|t| (true, t)))
737 .or_else(|| self.down.next().map(|t| (false, t)))
738 }
739}
740
741impl<'a, T> IntoIterator for &'a mut ZipList<T> {
742 type Item = (bool, &'a mut T);
743 type IntoIter = IterMut<'a, T>;
744
745 fn into_iter(self) -> IterMut<'a, T> {
746 self.iter_mut()
747 }
748}
749
750#[cfg(test)]
751mod tests {
752 use super::*;
753 use simple_test_case::test_case;
754
755 #[test]
756 fn focused() {
757 let s = ziplist!([1, 2], 3, [4, 5]);
758
759 assert_eq!(s.focused(), &3)
760 }
761
762 #[test]
763 fn head() {
764 let s = ziplist!([1, 2], 3, [4, 5]);
765
766 assert_eq!(s.head(), &1)
767 }
768
769 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!(3, [2, 1, 4, 5]); "items up and down")]
770 #[test_case(ziplist!([1, 2], 3), ziplist!(3, [2, 1]); "items up")]
771 #[test_case(ziplist!(3, [4, 5]), ziplist!(3, [4, 5]); "items down")]
772 #[test_case(ziplist!(3), ziplist!(3); "focus only")]
773 #[test]
774 fn swap_focus_and_head(mut s: ZipList<u8>, expected: ZipList<u8>) {
775 s.swap_focus_and_head();
776
777 assert_eq!(s, expected);
778 }
779
780 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!(3, [4, 5, 1, 2]); "items up and down")]
781 #[test_case(ziplist!([1, 2], 3), ziplist!(3, [1, 2]); "items up")]
782 #[test_case(ziplist!(3, [4, 5]), ziplist!(3, [4, 5]); "items down")]
783 #[test_case(ziplist!(3), ziplist!(3); "focus only")]
784 #[test]
785 fn rotate_focus_to_head(mut s: ZipList<u8>, expected: ZipList<u8>) {
786 s.rotate_focus_to_head();
787
788 assert_eq!(s, expected);
789 }
790
791 #[test_case(ziplist!([1, 2, 3], 4, [5, 6, 7]), ziplist!(1, [2, 3, 4, 5, 6, 7]); "items up and down")]
792 #[test_case(ziplist!([1, 2, 3], 4), ziplist!(1, [2, 3, 4]); "items up")]
793 #[test_case(ziplist!(3, [4, 5, 6]), ziplist!(3, [4, 5, 6]); "items down")]
794 #[test_case(ziplist!(3), ziplist!(3); "focus only")]
795 #[test]
796 fn focus_head(mut s: ZipList<u8>, expected: ZipList<u8>) {
797 s.focus_head();
798
799 assert_eq!(s, expected);
800 }
801
802 #[test_case(ziplist!([1, 2, 3], 4, [5, 6, 7]), ziplist!([1, 2, 3, 4, 5, 6], 7); "items up and down")]
803 #[test_case(ziplist!([1, 2, 3], 4), ziplist!([1, 2, 3], 4); "items up")]
804 #[test_case(ziplist!(3, [4, 5, 6]), ziplist!([3, 4, 5], 6); "items down")]
805 #[test_case(ziplist!(3), ziplist!(3); "focus only")]
806 #[test]
807 fn focus_tail(mut s: ZipList<u8>, expected: ZipList<u8>) {
808 s.focus_tail();
809
810 assert_eq!(s, expected);
811 }
812
813 #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e == 3, ziplist!([1, 2], 3, [4, 5, 6]); "current focus")]
814 #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e > 4, ziplist!([1, 2, 3, 4], 5, [6]); "in tail")]
815 #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e < 3 && e > 1, ziplist!([1], 2, [3, 4, 5, 6]); "in head")]
816 #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e < 3, ziplist!([], 1, [2, 3, 4, 5, 6]); "in head multiple matches")]
817 #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e == 42, ziplist!([1, 2], 3, [4, 5, 6]); "not found")]
818 #[test_case(ziplist!([1, 2], 3, [4, 5, 3, 6]), |&e| e == 42, ziplist!([1, 2], 3, [4, 5, 3, 6]); "not found with current focus duplicated")]
819 #[test]
820 fn focus_element_by(mut s: ZipList<u8>, predicate: fn(&u8) -> bool, expected: ZipList<u8>) {
821 s.focus_element_by(predicate);
822
823 assert_eq!(s, expected);
824 }
825
826 #[test]
827 fn iter_yields_all_elements_in_order() {
828 let s = ziplist!([1, 2], 3, [4, 5]);
829 let elems: Vec<(bool, u8)> = s.iter().map(|(b, t)| (b, *t)).collect();
830
831 assert_eq!(
832 elems,
833 vec![(false, 1), (false, 2), (true, 3), (false, 4), (false, 5)]
834 )
835 }
836
837 #[test]
838 fn iter_mut_yields_all_elements_in_order() {
839 let mut s = ziplist!([1, 2], 3, [4, 5]);
840 let elems: Vec<(bool, u8)> = s.iter_mut().map(|(b, t)| (b, *t)).collect();
841
842 assert_eq!(
843 elems,
844 vec![(false, 1), (false, 2), (true, 3), (false, 4), (false, 5)]
845 )
846 }
847
848 #[test]
849 fn into_iter_yields_all_elements_in_order() {
850 let s = ziplist!([1, 2], 3, [4, 5]);
851 let elems: Vec<(bool, u8)> = s.into_iter().collect();
852
853 assert_eq!(
854 elems,
855 vec![(false, 1), (false, 2), (true, 3), (false, 4), (false, 5)]
856 )
857 }
858
859 #[test]
860 fn map_preserves_structure() {
861 let s = ziplist!(["a", "bunch"], "of", ["string", "refs"]);
862
863 let mapped = s.map(|x| x.len());
864 let expected = ziplist!([1, 5], 2, [6, 4]);
865
866 assert_eq!(mapped, expected);
867 }
868
869 #[test_case(|&x| x > 5, None; "returns None if no elements satisfy the predicate")]
870 #[test_case(|x| x % 2 == 1, Some(ziplist!([3], 1, [5])); "holds focus with predicate")]
871 #[test_case(|x| x % 2 == 0, Some(ziplist!([2], 4)); "moves focus to top of down when possible")]
872 #[test_case(|&x| x == 2 || x == 3, Some(ziplist!([2], 3)); "moves focus to end of up if down is empty")]
873 #[test]
874 fn filter(predicate: fn(&usize) -> bool, expected: Option<ZipList<usize>>) {
875 let filtered = ziplist!([2, 3], 1, [4, 5]).filter(predicate);
876
877 assert_eq!(filtered, expected);
878 }
879
880 #[test_case(|&x| x > 5, None, vec![2,3,1,4,5]; "no elements satisfy the predicate")]
881 #[test_case(|x| x % 2 == 1, Some(ziplist!([3], 1, [5])), vec![2,4]; "holds focus with predicate")]
882 #[test_case(|x| x % 2 == 0, Some(ziplist!([2], 4)), vec![3,1,5]; "moves focus to top of down when possible")]
883 #[test_case(|&x| x == 2 || x == 3, Some(ziplist!([2], 3)), vec![1,4,5]; "moves focus to end of up if down is empty")]
884 #[test]
885 fn extract(
886 predicate: fn(&usize) -> bool,
887 expected: Option<ZipList<usize>>,
888 expected_extracted: Vec<usize>,
889 ) {
890 let (s, extracted) = ziplist!([2, 3], 1, [4, 5]).extract(predicate);
891
892 assert_eq!(s, expected);
893 assert_eq!(extracted, expected_extracted);
894 }
895
896 #[test]
897 fn flatten_is_correctly_ordered() {
898 let res = ziplist!([1, 2], 3, [4, 5]).flatten();
899
900 assert_eq!(res, vec![1, 2, 3, 4, 5]);
901 }
902
903 #[test]
904 fn try_from_iter_is_correctly_ordered() {
905 let res = ZipList::try_from_iter(vec![1, 2, 3, 4, 5]);
906
907 assert_eq!(res, Some(ziplist!(1, [2, 3, 4, 5])));
908 }
909
910 #[test]
911 fn try_from_iter_of_empty_iterable_is_none() {
912 let empty: Vec<()> = vec![];
913
914 assert_eq!(ZipList::try_from_iter(empty), None);
915 }
916
917 #[test]
918 fn try_from_iter_after_flatten_with_empty_up_is_inverse() {
919 let s = ziplist!(1, [2, 3, 4]);
920 let res = ZipList::try_from_iter(s.clone().flatten());
921
922 assert_eq!(res, Some(s));
923 }
924
925 #[test]
926 fn reverse_holds_focus() {
927 let mut s = ziplist!([1, 2], 3, [4, 5]);
928 s.reverse();
929
930 assert_eq!(s, ziplist!([5, 4], 3, [2, 1]));
931 }
932
933 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1], 2, [3, 4, 5]); "items up and down")]
934 #[test_case(ziplist!([], 1, [2, 3]), ziplist!([1, 2], 3); "items down only")]
935 #[test_case(ziplist!([1, 2], 3, []), ziplist!([1], 2, [3]); "items up only")]
936 #[test_case(ziplist!([], 1, []), ziplist!(1); "only focused")]
937 #[test]
938 fn focus_up(mut s: ZipList<usize>, expected: ZipList<usize>) {
939 s.focus_up();
940
941 assert_eq!(s, expected);
942 }
943
944 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1, 2, 3], 4, [5]); "items up and down")]
945 #[test_case(ziplist!(1, [2, 3]), ziplist!([1], 2, [3]); "items down only")]
946 #[test_case(ziplist!([1, 2], 3), ziplist!(1, [2, 3]); "items up only")]
947 #[test_case(ziplist!(1), ziplist!(1); "only focused")]
948 #[test]
949 fn focus_down(mut s: ZipList<usize>, expected: ZipList<usize>) {
950 s.focus_down();
951
952 assert_eq!(s, expected);
953 }
954
955 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1], 3, [2, 4, 5]); "items up and down")]
956 #[test_case(ziplist!(1, [2, 3]), ziplist!([2, 3], 1); "items down only")]
957 #[test_case(ziplist!([1, 2], 3), ziplist!([1], 3, [2]); "items up only")]
958 #[test_case(ziplist!(1), ziplist!(1); "only focused")]
959 #[test]
960 fn swap_up(mut s: ZipList<usize>, expected: ZipList<usize>) {
961 s.swap_up();
962
963 assert_eq!(s, expected);
964 }
965
966 #[test]
967 fn swap_up_chained() {
968 let mut s = ziplist!([1, 2], 3, [4]);
969
970 s.swap_up();
971 assert_eq!(s, ziplist!([1], 3, [2, 4]));
972 s.swap_up();
973 assert_eq!(s, ziplist!(3, [1, 2, 4]));
974 s.swap_up();
975 assert_eq!(s, ziplist!([1, 2, 4], 3));
976 }
977
978 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1, 2, 4], 3, [5]); "items up and down")]
979 #[test_case(ziplist!(1, [2, 3]), ziplist!([2], 1, [3]); "items down only")]
980 #[test_case(ziplist!([1, 2], 3), ziplist!(3, [1, 2]); "items up only")]
981 #[test_case(ziplist!(1), ziplist!(1); "only focused")]
982 #[test]
983 fn swap_down(mut s: ZipList<usize>, expected: ZipList<usize>) {
984 s.swap_down();
985
986 assert_eq!(s, expected);
987 }
988
989 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([2], 3, [4, 5, 1]); "items up and down")]
990 #[test_case(ziplist!(1, [2, 3]), ziplist!([2, 3], 1); "items down only")]
991 #[test_case(ziplist!([1, 2], 3), ziplist!([2], 3, [1]); "items up only")]
992 #[test_case(ziplist!(1), ziplist!(1); "only focused")]
993 #[test]
994 fn rotate_up(mut s: ZipList<usize>, expected: ZipList<usize>) {
995 s.rotate_up();
996
997 assert_eq!(s, expected);
998 }
999
1000 #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([5, 1, 2], 3, [4]); "items up and down")]
1001 #[test_case(ziplist!(1, [2, 3]), ziplist!([3], 1, [2]); "items down only")]
1002 #[test_case(ziplist!([1, 2], 3), ziplist!(3, [1, 2]); "items up only")]
1003 #[test_case(ziplist!(1), ziplist!(1); "only focused")]
1004 #[test]
1005 fn rotate_down(mut s: ZipList<usize>, expected: ZipList<usize>) {
1006 s.rotate_down();
1007
1008 assert_eq!(s, expected);
1009 }
1010
1011 #[test_case(Position::Focus, ziplist!([1,2], 6, [3,4,5]); "focus")]
1012 #[test_case(Position::Before, ziplist!([1,2,6], 3, [4,5]); "before")]
1013 #[test_case(Position::After, ziplist!([1,2], 3, [6,4,5]); "after")]
1014 #[test_case(Position::Head, ziplist!([6,1,2], 3, [4,5]); "head")]
1015 #[test_case(Position::Tail, ziplist!([1,2], 3, [4,5,6]); "tail")]
1016 #[test]
1017 fn insert_at(pos: Position, expected: ZipList<usize>) {
1018 let mut s = ziplist!([1, 2], 3, [4, 5]);
1019 s.insert_at(pos, 6);
1020
1021 assert_eq!(s, expected);
1022 }
1023
1024 #[test_case(ziplist!([1,2,3,4], 5, []); "up and focus")]
1025 #[test_case(ziplist!([], 1, [2,3,4,5]); "focus and down")]
1026 #[test_case(ziplist!([1,2], 3, [4,5]); "all")]
1027 #[test_case(ziplist!([], 1, []); "focus only")]
1028 #[test]
1029 fn index(zl: ZipList<usize>) {
1030 for i in 0..zl.len() {
1031 assert_eq!(zl[i], i + 1, "i={i}");
1032 }
1033 }
1034
1035 #[test_case(ziplist!([1,2,3,4], 5, []); "up and focus")]
1036 #[test_case(ziplist!([], 1, [2,3,4,5]); "focus and down")]
1037 #[test_case(ziplist!([1,2], 3, [4,5]); "all")]
1038 #[test_case(ziplist!([], 1, []); "focus only")]
1039 #[test]
1040 fn index_mut(mut zl: ZipList<usize>) {
1041 let expected = zl.clone().map(|_| 6);
1042
1043 #[allow(clippy::manual_slice_fill)]
1045 for i in 0..zl.len() {
1046 zl[i] = 6;
1047 }
1048
1049 assert_eq!(zl, expected);
1050 }
1051}