ad_editor/
ziplist.rs

1//! Copied from the penrose crate Stack impl.
2//!
3//! Really this should be published as its own crate.
4use std::{
5    collections::vec_deque::{self, VecDeque},
6    fmt,
7    iter::{once, IntoIterator},
8    mem::{swap, take},
9};
10
11#[macro_export]
12macro_rules! ziplist {
13    ([$($up:expr),*], $focus:expr, [$($down:expr),*]) => { $crate::ziplist::ZipList::new([$($up),*], $focus, [$($down),*]) };
14    ([$($up:expr),*], $focus:expr) => { $crate::ziplist::ZipList::new([$($up),*], $focus, []) };
15    ($focus:expr, [$($down:expr),*]) => { $crate::ziplist::ZipList::new([], $focus, [$($down),*]) };
16    ($focus:expr, $($down:expr),+) => { $crate::ziplist::ZipList::new([], $focus, [$($down),*]) };
17    ($focus:expr) => { $crate::ziplist::ZipList::new([], $focus, []) };
18}
19
20macro_rules! pop_where {
21    ($self:ident, $lst:ident, $($pred:tt)+) => {{
22        let placeholder = ::std::mem::take(&mut $self.$lst);
23        let mut remaining = ::std::collections::VecDeque::default();
24        let mut popped = None;
25        let pred = $($pred)+;
26
27        for item in placeholder.into_iter() {
28            if pred(&item) {
29                popped = Some(item);
30            } else {
31                remaining.push_back(item);
32            }
33        }
34
35        ::std::mem::swap(&mut $self.$lst, &mut remaining);
36
37        popped
38    }};
39}
40
41/// A position within a [ZipList].
42#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
43pub enum Position {
44    /// The current focus point
45    #[default]
46    Focus,
47    /// Above the current focus point
48    Before,
49    /// Below the current focus point
50    After,
51    /// The first element of the stack
52    Head,
53    /// The last element of the stack
54    Tail,
55}
56
57/// A [ZipList] can be thought of as a linked list with a hole punched in it to mark
58/// a single element that currently holds focus (though in practice it is implemented
59/// using a [VecDeque] for efficiency purposes). By convention, the main element is
60/// the first element in the stack (regardless of focus). Focusing operations do not
61/// reorder the elements of the stack or the resulting [Vec] that can be obtained
62/// from calling [ZipList::flatten].
63///
64/// This is a [zipper](https://en.wikipedia.org/wiki/Zipper_(data_structure))
65/// over a [VecDeque]. Many of the methods that mutate the structure of the ZipList
66/// return back a mutable reference so that they are able to be chained.
67#[derive(Debug, Default, Clone, PartialEq, Eq)]
68pub struct ZipList<T> {
69    pub(crate) up: VecDeque<T>,
70    pub(crate) focus: T,
71    pub(crate) down: VecDeque<T>,
72}
73
74impl<T: fmt::Display> fmt::Display for ZipList<T> {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        let up: Vec<String> = self.up.iter().rev().map(|t| t.to_string()).collect();
77        let down: Vec<String> = self.down.iter().map(|t| t.to_string()).collect();
78
79        write!(
80            f,
81            "ZipList([{}], {}, [{}])",
82            up.join(", "),
83            self.focus,
84            down.join(", ")
85        )
86    }
87}
88
89impl<T> ZipList<T> {
90    /// Create a new ZipList specifying the focused element and and elements
91    /// above and below it.
92    pub fn new<I, J>(up: I, focus: T, down: J) -> Self
93    where
94        I: IntoIterator<Item = T>,
95        J: IntoIterator<Item = T>,
96    {
97        let mut reversed_up = VecDeque::new();
98        for elem in up.into_iter() {
99            reversed_up.push_front(elem);
100        }
101
102        Self {
103            focus,
104            up: reversed_up,
105            down: down.into_iter().collect(),
106        }
107    }
108
109    // NOTE: Can't implement FromIterator<T> because we disallow an empty stack
110    /// For an iterator of at least one element, the first element will
111    /// be focused and all remaining elements will be placed after it.
112    /// For an empty iterator, return None.
113    pub fn try_from_iter<I>(iter: I) -> Option<Self>
114    where
115        I: IntoIterator<Item = T>,
116    {
117        let mut it = iter.into_iter();
118        let focus = it.next()?;
119
120        Some(Self {
121            up: VecDeque::default(),
122            focus,
123            down: it.collect(),
124        })
125    }
126
127    /// The number of elements in this ZipList.
128    pub fn len(&self) -> usize {
129        self.up.len() + self.down.len() + 1
130    }
131
132    /// Always false: a ZipList always has at least one focused element.
133    pub fn is_empty(&self) -> bool {
134        false
135    }
136
137    /// Provide an iterator over this stack iterating over up,
138    /// focus and then down.
139    pub fn iter(&self) -> Iter<'_, T> {
140        Iter {
141            up: self.up.iter(),
142            focus: Some(&self.focus),
143            down: self.down.iter(),
144        }
145    }
146
147    /// Provide an iterator over this stack iterating over up,
148    /// focus and then down with mutable references.
149    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
150        IterMut {
151            up: self.up.iter_mut(),
152            focus: Some(&mut self.focus),
153            down: self.down.iter_mut(),
154        }
155    }
156
157    /// Iterate over the clients in this stack from the the focused element
158    /// down through the stack.
159    pub fn unravel(&self) -> impl Iterator<Item = &T> {
160        once(&self.focus)
161            .chain(self.down.iter())
162            .chain(self.up.iter().rev())
163    }
164
165    /// Flatten a ZipList into a Vector, losing the information of which
166    /// element is focused.
167    pub fn flatten(self) -> Vec<T> {
168        self.into_iter().map(|(_, t)| t).collect()
169    }
170
171    /// Return a reference to the first element in this [ZipList]
172    pub fn head(&self) -> &T {
173        self.up.back().unwrap_or(&self.focus)
174    }
175
176    /// Return a reference to the focused element in this [ZipList]
177    pub fn focused(&self) -> &T {
178        &self.focus
179    }
180
181    /// Return a reference to the last element in this [ZipList]
182    pub fn last(&self) -> &T {
183        self.down.back().unwrap_or(&self.focus)
184    }
185
186    pub fn last_mut(&mut self) -> &mut T {
187        self.down.back_mut().unwrap_or(&mut self.focus)
188    }
189
190    /// Swap the current head element with the focused element in the
191    /// stack order. Focus stays with the original focused element.
192    pub fn swap_focus_and_head(&mut self) -> &mut Self {
193        let mut tmp = take(&mut self.up);
194
195        if let Some(head) = tmp.pop_back() {
196            self.down.push_front(head);
197        }
198
199        for item in tmp.into_iter() {
200            self.down.push_front(item);
201        }
202
203        self
204    }
205
206    /// Rotate the ZipList until the current focused element is in the head position
207    pub fn rotate_focus_to_head(&mut self) -> &mut Self {
208        if self.up.is_empty() {
209            return self;
210        }
211
212        for item in take(&mut self.up).into_iter().rev() {
213            self.down.push_back(item);
214        }
215
216        self
217    }
218
219    /// Move focus to the element in the head position
220    pub fn focus_head(&mut self) -> &mut Self {
221        let mut head = match self.up.pop_back() {
222            None => return self, // focus is already head
223            Some(t) => t,
224        };
225
226        swap(&mut head, &mut self.focus);
227        self.down.push_front(head);
228
229        for item in take(&mut self.up).into_iter() {
230            self.down.push_front(item);
231        }
232
233        self
234    }
235
236    /// Move focus to the element in the head position
237    pub fn focus_tail(&mut self) -> &mut Self {
238        let mut tail = match self.down.pop_back() {
239            None => return self, // focus is already tail
240            Some(t) => t,
241        };
242
243        swap(&mut tail, &mut self.focus);
244        self.up.push_front(tail);
245
246        for item in take(&mut self.down).into_iter() {
247            self.up.push_front(item);
248        }
249
250        self
251    }
252
253    /// Insert the given element in place of the current focus, pushing
254    /// the current focus down the [ZipList].
255    pub fn insert(&mut self, t: T) -> &mut Self {
256        self.insert_at(Position::default(), t)
257    }
258
259    /// Insert the given element at the requested position in the [ZipList].
260    /// See [Position] for the semantics of each case. For all cases, the
261    /// existing elements in the [ZipList] are pushed down to make room for
262    /// the new one.
263    pub fn insert_at(&mut self, pos: Position, mut t: T) -> &mut Self {
264        use Position::*;
265
266        match pos {
267            Focus => {
268                self.swap_focus(&mut t);
269                self.down.push_front(t);
270            }
271            Before => self.up.push_front(t),
272            After => self.down.push_front(t),
273            Head => self.up.push_back(t),
274            Tail => self.down.push_back(t),
275        };
276
277        self
278    }
279
280    /// Remove the focused element of this ZipList. If this was the only element then
281    /// the stack is dropped and None is returned.
282    pub fn remove_focused(mut self) -> (T, Option<Self>) {
283        let focus = match self.down.pop_front().or_else(|| self.up.pop_front()) {
284            Some(focus) => focus,
285            None => return (self.focus, None),
286        };
287
288        (
289            self.focus,
290            Some(Self {
291                focus,
292                up: self.up,
293                down: self.down,
294            }),
295        )
296    }
297
298    /// Removed the focused element of this Ziplist.
299    ///
300    /// # Panics
301    /// Panics if the focus was the only element
302    pub fn remove_focused_unchecked(&mut self) -> T {
303        let mut focus = self
304            .down
305            .pop_front()
306            .or_else(|| self.up.pop_front())
307            .expect("Ziplist only contained a single element");
308        swap(&mut focus, &mut self.focus);
309
310        focus
311    }
312
313    /// Remove the first element that matches the given predicate function. If doing so would
314    /// remove the last element of the ZipList then `default_focus` is called to ensure that there
315    /// is a single element remaining as the current focus.
316    pub fn remove_where_with_default(
317        &mut self,
318        pred: impl Fn(&T) -> bool,
319        default: impl Fn() -> T,
320    ) -> Option<T> {
321        if let Some(found) = pop_where!(self, up, |elem: &T| pred(elem)) {
322            return Some(found);
323        } else if let Some(found) = pop_where!(self, down, |elem: &T| pred(elem)) {
324            return Some(found);
325        }
326
327        if pred(&self.focus) {
328            let mut focus = match self.down.pop_front().or_else(|| self.up.pop_front()) {
329                Some(focus) => focus,
330                None => default(),
331            };
332            swap(&mut focus, &mut self.focus);
333
334            Some(focus)
335        } else {
336            None
337        }
338    }
339
340    /// Map a function over all elements in this [ZipList], returning a new one.
341    pub fn map<F, U>(self, f: F) -> ZipList<U>
342    where
343        F: Fn(T) -> U,
344    {
345        ZipList {
346            focus: f(self.focus),
347            up: self.up.into_iter().map(&f).collect(),
348            down: self.down.into_iter().map(&f).collect(),
349        }
350    }
351
352    /// Retain only elements which satisfy the given predicate. If the focused
353    /// element is removed then focus shifts to the first remaining element
354    /// after it, if there are no elements after then focus moves to the first
355    /// remaining element before. If no elements satisfy the predicate then
356    /// None is returned.
357    pub fn filter<F>(self, f: F) -> Option<Self>
358    where
359        F: Fn(&T) -> bool,
360    {
361        let new_stack = Self {
362            focus: self.focus,
363            up: self.up.into_iter().filter(&f).collect(),
364            down: self.down.into_iter().filter(&f).collect(),
365        };
366
367        if f(&new_stack.focus) {
368            Some(new_stack)
369        } else {
370            let (_, maybe_stack) = new_stack.remove_focused();
371            maybe_stack
372        }
373    }
374
375    pub fn filter_unchecked<F>(&mut self, f: F)
376    where
377        F: Fn(&T) -> bool,
378    {
379        self.up.retain(&f);
380        self.down.retain(&f);
381
382        if !f(&self.focus) {
383            self.remove_focused_unchecked();
384        }
385    }
386
387    /// Reverse the ordering of a ZipList (up becomes down) while maintaining
388    /// focus.
389    #[inline]
390    pub fn reverse(&mut self) -> &mut Self {
391        swap(&mut self.up, &mut self.down);
392
393        self
394    }
395
396    #[inline]
397    pub(crate) fn swap_focus(&mut self, new: &mut T) {
398        swap(&mut self.focus, new);
399    }
400
401    #[inline]
402    fn rev_up(&mut self) -> &mut Self {
403        let mut reversed = take(&mut self.up).into_iter().rev().collect();
404        swap(&mut self.up, &mut reversed);
405
406        self
407    }
408
409    #[inline]
410    fn rev_down(&mut self) -> &mut Self {
411        let mut reversed = take(&mut self.down).into_iter().rev().collect();
412        swap(&mut self.down, &mut reversed);
413
414        self
415    }
416
417    /// Move focus from the current element up the stack, wrapping to the
418    /// bottom if focus is already at the top.
419    pub fn focus_up(&mut self) -> &mut Self {
420        match (self.up.is_empty(), self.down.is_empty()) {
421            // xs:x f ys   -> xs x f:ys
422            // xs:x f []   -> xs x f
423            (false, _) => {
424                let mut focus = self.up.pop_front().expect("non-empty");
425                self.swap_focus(&mut focus);
426                self.down.push_front(focus);
427            }
428
429            // [] f ys:y   -> f:ys y []
430            (true, false) => {
431                let mut focus = self.down.pop_back().expect("non-empty");
432                self.swap_focus(&mut focus);
433                self.down.push_front(focus);
434                self.reverse().rev_up();
435            }
436
437            // [] f []     -> [] f []
438            (true, true) => (),
439        }
440
441        self
442    }
443
444    /// Move focus from the current element down the stack, wrapping to the
445    /// top if focus is already at the bottom.
446    pub fn focus_down(&mut self) -> &mut Self {
447        match (self.up.is_empty(), self.down.is_empty()) {
448            // xs f y:ys   -> xs:f y ys
449            // [] f y:ys   -> f y ys
450            (_, false) => {
451                let mut focus = self.down.pop_front().expect("non-empty");
452                self.swap_focus(&mut focus);
453                self.up.push_front(focus);
454            }
455
456            // x:xs f []   -> [] x xs:f
457            (false, true) => {
458                let mut focus = self.up.pop_back().expect("non-empty");
459                self.swap_focus(&mut focus);
460                self.up.push_front(focus);
461                self.reverse().rev_down();
462            }
463
464            // [] f []     -> [] f []
465            (true, true) => (),
466        }
467
468        self
469    }
470
471    /// Focus the first element found matching the given predicate function.
472    ///
473    /// Returns true if the focused element changed. If no matching elements are found,
474    /// the ZipList will be left in its original state and false is returned.
475    pub fn focus_element_by<F>(&mut self, f: F) -> bool
476    where
477        F: Fn(&T) -> bool,
478    {
479        for _ in 0..self.len() {
480            if f(&self.focus) {
481                return true;
482            }
483            self.focus_down();
484        }
485
486        false
487    }
488
489    /// Focus the first element found matching the given predicate function.
490    ///
491    /// If no matching elements are found, the ZipList will be left in
492    /// its original state.
493    pub fn focus_element_by_mut<F>(&mut self, f: F) -> bool
494    where
495        F: Fn(&mut T) -> bool,
496    {
497        for _ in 0..self.len() {
498            if f(&mut self.focus) {
499                return true;
500            }
501            self.focus_down();
502        }
503
504        false
505    }
506
507    /// Swap the focused element with the one above, wrapping from top to bottom.
508    /// The currently focused element is maintained by this operation.
509    pub fn swap_up(&mut self) -> &mut Self {
510        match self.up.pop_front() {
511            Some(t) => {
512                self.down.push_front(t);
513                self
514            }
515            None => self.reverse().rev_up(),
516        }
517    }
518
519    /// Swap the focused element with the one below, wrapping from top to bottom.
520    /// The currently focused element is maintained by this operation.
521    pub fn swap_down(&mut self) -> &mut Self {
522        match self.down.pop_front() {
523            Some(t) => {
524                self.up.push_front(t);
525                self
526            }
527            None => self.reverse().rev_down(),
528        }
529    }
530
531    /// Rotate all elements of the stack forward, wrapping from top to bottom.
532    /// The currently focused element in the stack is maintained by this operation.
533    pub fn rotate_up(&mut self) -> &mut Self {
534        match self.up.pop_back() {
535            Some(t) => {
536                self.down.push_back(t);
537                self
538            }
539            None => self.reverse().rev_up(),
540        }
541    }
542
543    /// Rotate all elements of the stack back, wrapping from bottom to top.
544    /// The currently focused element in the stack is maintained by this operation.
545    pub fn rotate_down(&mut self) -> &mut Self {
546        match self.down.pop_back() {
547            Some(t) => {
548                self.up.push_back(t);
549                self
550            }
551            None => self.reverse().rev_down(),
552        }
553    }
554}
555
556impl<T: Clone> ZipList<T> {
557    /// Extract elements satisfying a predicate into a Vec, leaving remaining
558    /// elements in their original stack position.
559    pub fn extract<F>(&self, f: F) -> (Option<Self>, Vec<T>)
560    where
561        F: Fn(&T) -> bool,
562    {
563        let mut extracted = Vec::new();
564        let mut new_stack = Self {
565            focus: self.focus.clone(),
566            up: Default::default(),
567            down: Default::default(),
568        };
569
570        for t in self.up.clone().into_iter().rev() {
571            if f(&t) {
572                new_stack.up.push_front(t);
573            } else {
574                extracted.push(t);
575            }
576        }
577
578        let up_to_focus = extracted.len();
579
580        for t in self.down.clone().into_iter() {
581            if f(&t) {
582                new_stack.down.push_back(t);
583            } else {
584                extracted.push(t);
585            }
586        }
587
588        if f(&new_stack.focus) {
589            return (Some(new_stack), extracted);
590        }
591
592        let (t, maybe_stack) = new_stack.remove_focused();
593        extracted.insert(up_to_focus, t);
594
595        (maybe_stack, extracted)
596    }
597}
598
599impl<T: PartialEq> ZipList<T> {
600    /// Check whether a given element is in this ZipList
601    pub fn contains(&self, t: &T) -> bool {
602        &self.focus == t || self.up.contains(t) || self.down.contains(t)
603    }
604
605    /// Attempt to focus a given element in the [ZipList] if it is present.
606    ///
607    /// If the requested element is not found, the ZipList will be left in
608    /// its original state.
609    pub fn focus_element(&mut self, t: &T) {
610        self.focus_element_by(|elem| elem == t);
611    }
612
613    /// Remove an element from the stack.
614    ///
615    /// If the element was present it is returned along with the rest of the [ZipList].
616    /// If this was the last element in the stack, the stack is dropped and None is
617    /// returned.
618    pub fn remove(mut self, t: &T) -> (Option<T>, Option<Self>) {
619        if let Some(found) = pop_where!(self, up, |elem: &T| elem == t) {
620            return (Some(found), Some(self));
621        }
622
623        if let Some(found) = pop_where!(self, down, |elem: &T| elem == t) {
624            return (Some(found), Some(self));
625        }
626
627        if t == &self.focus {
628            let (focus, stack) = self.remove_focused();
629            (Some(focus), stack)
630        } else {
631            (None, Some(self))
632        }
633    }
634}
635
636// Iteration
637
638/// An owned iterator over a [ZipList].
639#[derive(Debug)]
640pub struct IntoIter<T> {
641    up: VecDeque<T>,
642    focus: Option<T>,
643    down: VecDeque<T>,
644}
645
646impl<T> Iterator for IntoIter<T> {
647    type Item = (bool, T);
648
649    fn next(&mut self) -> Option<Self::Item> {
650        self.up
651            .pop_back()
652            .map(|t| (false, t))
653            .or_else(|| self.focus.take().map(|t| (true, t)))
654            .or_else(|| self.down.pop_front().map(|t| (false, t)))
655    }
656}
657
658impl<T> IntoIterator for ZipList<T> {
659    type Item = (bool, T);
660    type IntoIter = IntoIter<T>;
661
662    fn into_iter(self) -> IntoIter<T> {
663        IntoIter {
664            up: self.up,
665            focus: Some(self.focus),
666            down: self.down,
667        }
668    }
669}
670
671/// An iterator over a [ZipList].
672#[derive(Debug)]
673pub struct Iter<'a, T> {
674    up: vec_deque::Iter<'a, T>,
675    focus: Option<&'a T>,
676    down: vec_deque::Iter<'a, T>,
677}
678
679impl<'a, T> Iterator for Iter<'a, T> {
680    type Item = (bool, &'a T);
681
682    fn next(&mut self) -> Option<Self::Item> {
683        self.up
684            .next_back()
685            .map(|t| (false, t))
686            .or_else(|| self.focus.take().map(|t| (true, t)))
687            .or_else(|| self.down.next().map(|t| (false, t)))
688    }
689}
690
691impl<'a, T> IntoIterator for &'a ZipList<T> {
692    type Item = (bool, &'a T);
693    type IntoIter = Iter<'a, T>;
694
695    fn into_iter(self) -> Iter<'a, T> {
696        self.iter()
697    }
698}
699
700/// A mutable iterator over a [ZipList].
701#[derive(Debug)]
702pub struct IterMut<'a, T> {
703    up: vec_deque::IterMut<'a, T>,
704    focus: Option<&'a mut T>,
705    down: vec_deque::IterMut<'a, T>,
706}
707
708impl<'a, T> Iterator for IterMut<'a, T> {
709    type Item = (bool, &'a mut T);
710
711    fn next(&mut self) -> Option<Self::Item> {
712        self.up
713            .next_back()
714            .map(|t| (false, t))
715            .or_else(|| self.focus.take().map(|t| (true, t)))
716            .or_else(|| self.down.next().map(|t| (false, t)))
717    }
718}
719
720impl<'a, T> IntoIterator for &'a mut ZipList<T> {
721    type Item = (bool, &'a mut T);
722    type IntoIter = IterMut<'a, T>;
723
724    fn into_iter(self) -> IterMut<'a, T> {
725        self.iter_mut()
726    }
727}
728
729#[cfg(test)]
730mod tests {
731    use super::*;
732    use simple_test_case::test_case;
733
734    #[test]
735    fn focused() {
736        let s = ziplist!([1, 2], 3, [4, 5]);
737
738        assert_eq!(s.focused(), &3)
739    }
740
741    #[test]
742    fn head() {
743        let s = ziplist!([1, 2], 3, [4, 5]);
744
745        assert_eq!(s.head(), &1)
746    }
747
748    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!(3, [2, 1, 4, 5]); "items up and down")]
749    #[test_case(ziplist!([1, 2], 3), ziplist!(3, [2, 1]); "items up")]
750    #[test_case(ziplist!(3, [4, 5]), ziplist!(3, [4, 5]); "items down")]
751    #[test_case(ziplist!(3), ziplist!(3); "focus only")]
752    #[test]
753    fn swap_focus_and_head(mut s: ZipList<u8>, expected: ZipList<u8>) {
754        s.swap_focus_and_head();
755
756        assert_eq!(s, expected);
757    }
758
759    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!(3, [4, 5, 1, 2]); "items up and down")]
760    #[test_case(ziplist!([1, 2], 3), ziplist!(3, [1, 2]); "items up")]
761    #[test_case(ziplist!(3, [4, 5]), ziplist!(3, [4, 5]); "items down")]
762    #[test_case(ziplist!(3), ziplist!(3); "focus only")]
763    #[test]
764    fn rotate_focus_to_head(mut s: ZipList<u8>, expected: ZipList<u8>) {
765        s.rotate_focus_to_head();
766
767        assert_eq!(s, expected);
768    }
769
770    #[test_case(ziplist!([1, 2, 3], 4, [5, 6, 7]), ziplist!(1, [2, 3, 4, 5, 6, 7]); "items up and down")]
771    #[test_case(ziplist!([1, 2, 3], 4), ziplist!(1, [2, 3, 4]); "items up")]
772    #[test_case(ziplist!(3, [4, 5, 6]), ziplist!(3, [4, 5, 6]); "items down")]
773    #[test_case(ziplist!(3), ziplist!(3); "focus only")]
774    #[test]
775    fn focus_head(mut s: ZipList<u8>, expected: ZipList<u8>) {
776        s.focus_head();
777
778        assert_eq!(s, expected);
779    }
780
781    #[test_case(ziplist!([1, 2, 3], 4, [5, 6, 7]), ziplist!([1, 2, 3, 4, 5, 6], 7); "items up and down")]
782    #[test_case(ziplist!([1, 2, 3], 4), ziplist!([1, 2, 3], 4); "items up")]
783    #[test_case(ziplist!(3, [4, 5, 6]), ziplist!([3, 4, 5], 6); "items down")]
784    #[test_case(ziplist!(3), ziplist!(3); "focus only")]
785    #[test]
786    fn focus_tail(mut s: ZipList<u8>, expected: ZipList<u8>) {
787        s.focus_tail();
788
789        assert_eq!(s, expected);
790    }
791
792    #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e == 3, ziplist!([1, 2], 3, [4, 5, 6]); "current focus")]
793    #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e > 4, ziplist!([1, 2, 3, 4], 5, [6]); "in tail")]
794    #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e < 3 && e > 1, ziplist!([1], 2, [3, 4, 5, 6]); "in head")]
795    #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e < 3, ziplist!([], 1, [2, 3, 4, 5, 6]); "in head multiple matches")]
796    #[test_case(ziplist!([1, 2], 3, [4, 5, 6]), |&e| e == 42, ziplist!([1, 2], 3, [4, 5, 6]); "not found")]
797    #[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")]
798    #[test]
799    fn focus_element_by(mut s: ZipList<u8>, predicate: fn(&u8) -> bool, expected: ZipList<u8>) {
800        s.focus_element_by(predicate);
801
802        assert_eq!(s, expected);
803    }
804
805    #[test]
806    fn iter_yields_all_elements_in_order() {
807        let s = ziplist!([1, 2], 3, [4, 5]);
808        let elems: Vec<(bool, u8)> = s.iter().map(|(b, t)| (b, *t)).collect();
809
810        assert_eq!(
811            elems,
812            vec![(false, 1), (false, 2), (true, 3), (false, 4), (false, 5)]
813        )
814    }
815
816    #[test]
817    fn iter_mut_yields_all_elements_in_order() {
818        let mut s = ziplist!([1, 2], 3, [4, 5]);
819        let elems: Vec<(bool, u8)> = s.iter_mut().map(|(b, t)| (b, *t)).collect();
820
821        assert_eq!(
822            elems,
823            vec![(false, 1), (false, 2), (true, 3), (false, 4), (false, 5)]
824        )
825    }
826
827    #[test]
828    fn into_iter_yields_all_elements_in_order() {
829        let s = ziplist!([1, 2], 3, [4, 5]);
830        let elems: Vec<(bool, u8)> = s.into_iter().collect();
831
832        assert_eq!(
833            elems,
834            vec![(false, 1), (false, 2), (true, 3), (false, 4), (false, 5)]
835        )
836    }
837
838    #[test]
839    fn map_preserves_structure() {
840        let s = ziplist!(["a", "bunch"], "of", ["string", "refs"]);
841
842        let mapped = s.map(|x| x.len());
843        let expected = ziplist!([1, 5], 2, [6, 4]);
844
845        assert_eq!(mapped, expected);
846    }
847
848    #[test_case(|&x| x > 5, None; "returns None if no elements satisfy the predicate")]
849    #[test_case(|x| x % 2 == 1, Some(ziplist!([3], 1, [5])); "holds focus with predicate")]
850    #[test_case(|x| x % 2 == 0, Some(ziplist!([2], 4)); "moves focus to top of down when possible")]
851    #[test_case(|&x| x == 2 || x == 3, Some(ziplist!([2], 3)); "moves focus to end of up if down is empty")]
852    #[test]
853    fn filter(predicate: fn(&usize) -> bool, expected: Option<ZipList<usize>>) {
854        let filtered = ziplist!([2, 3], 1, [4, 5]).filter(predicate);
855
856        assert_eq!(filtered, expected);
857    }
858
859    #[test_case(|&x| x > 5, None, vec![2,3,1,4,5]; "no elements satisfy the predicate")]
860    #[test_case(|x| x % 2 == 1, Some(ziplist!([3], 1, [5])), vec![2,4]; "holds focus with predicate")]
861    #[test_case(|x| x % 2 == 0, Some(ziplist!([2], 4)), vec![3,1,5]; "moves focus to top of down when possible")]
862    #[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")]
863    #[test]
864    fn extract(
865        predicate: fn(&usize) -> bool,
866        expected: Option<ZipList<usize>>,
867        expected_extracted: Vec<usize>,
868    ) {
869        let (s, extracted) = ziplist!([2, 3], 1, [4, 5]).extract(predicate);
870
871        assert_eq!(s, expected);
872        assert_eq!(extracted, expected_extracted);
873    }
874
875    #[test]
876    fn flatten_is_correctly_ordered() {
877        let res = ziplist!([1, 2], 3, [4, 5]).flatten();
878
879        assert_eq!(res, vec![1, 2, 3, 4, 5]);
880    }
881
882    #[test]
883    fn try_from_iter_is_correctly_ordered() {
884        let res = ZipList::try_from_iter(vec![1, 2, 3, 4, 5]);
885
886        assert_eq!(res, Some(ziplist!(1, [2, 3, 4, 5])));
887    }
888
889    #[test]
890    fn try_from_iter_of_empty_iterable_is_none() {
891        let empty: Vec<()> = vec![];
892
893        assert_eq!(ZipList::try_from_iter(empty), None);
894    }
895
896    #[test]
897    fn try_from_iter_after_flatten_with_empty_up_is_inverse() {
898        let s = ziplist!(1, [2, 3, 4]);
899        let res = ZipList::try_from_iter(s.clone().flatten());
900
901        assert_eq!(res, Some(s));
902    }
903
904    #[test]
905    fn reverse_holds_focus() {
906        let mut s = ziplist!([1, 2], 3, [4, 5]);
907        s.reverse();
908
909        assert_eq!(s, ziplist!([5, 4], 3, [2, 1]));
910    }
911
912    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1], 2, [3, 4, 5]); "items up and down")]
913    #[test_case(ziplist!([], 1, [2, 3]), ziplist!([1, 2], 3); "items down only")]
914    #[test_case(ziplist!([1, 2], 3, []), ziplist!([1], 2, [3]); "items up only")]
915    #[test_case(ziplist!([], 1, []), ziplist!(1); "only focused")]
916    #[test]
917    fn focus_up(mut s: ZipList<usize>, expected: ZipList<usize>) {
918        s.focus_up();
919
920        assert_eq!(s, expected);
921    }
922
923    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1, 2, 3], 4, [5]); "items up and down")]
924    #[test_case(ziplist!(1, [2, 3]), ziplist!([1], 2, [3]); "items down only")]
925    #[test_case(ziplist!([1, 2], 3), ziplist!(1, [2, 3]); "items up only")]
926    #[test_case(ziplist!(1), ziplist!(1); "only focused")]
927    #[test]
928    fn focus_down(mut s: ZipList<usize>, expected: ZipList<usize>) {
929        s.focus_down();
930
931        assert_eq!(s, expected);
932    }
933
934    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1], 3, [2, 4, 5]); "items up and down")]
935    #[test_case(ziplist!(1, [2, 3]), ziplist!([2, 3], 1); "items down only")]
936    #[test_case(ziplist!([1, 2], 3), ziplist!([1], 3, [2]); "items up only")]
937    #[test_case(ziplist!(1), ziplist!(1); "only focused")]
938    #[test]
939    fn swap_up(mut s: ZipList<usize>, expected: ZipList<usize>) {
940        s.swap_up();
941
942        assert_eq!(s, expected);
943    }
944
945    #[test]
946    fn swap_up_chained() {
947        let mut s = ziplist!([1, 2], 3, [4]);
948
949        s.swap_up();
950        assert_eq!(s, ziplist!([1], 3, [2, 4]));
951        s.swap_up();
952        assert_eq!(s, ziplist!(3, [1, 2, 4]));
953        s.swap_up();
954        assert_eq!(s, ziplist!([1, 2, 4], 3));
955    }
956
957    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([1, 2, 4], 3, [5]); "items up and down")]
958    #[test_case(ziplist!(1, [2, 3]), ziplist!([2], 1, [3]); "items down only")]
959    #[test_case(ziplist!([1, 2], 3), ziplist!(3, [1, 2]); "items up only")]
960    #[test_case(ziplist!(1), ziplist!(1); "only focused")]
961    #[test]
962    fn swap_down(mut s: ZipList<usize>, expected: ZipList<usize>) {
963        s.swap_down();
964
965        assert_eq!(s, expected);
966    }
967
968    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([2], 3, [4, 5, 1]); "items up and down")]
969    #[test_case(ziplist!(1, [2, 3]), ziplist!([2, 3], 1); "items down only")]
970    #[test_case(ziplist!([1, 2], 3), ziplist!([2], 3, [1]); "items up only")]
971    #[test_case(ziplist!(1), ziplist!(1); "only focused")]
972    #[test]
973    fn rotate_up(mut s: ZipList<usize>, expected: ZipList<usize>) {
974        s.rotate_up();
975
976        assert_eq!(s, expected);
977    }
978
979    #[test_case(ziplist!([1, 2], 3, [4, 5]), ziplist!([5, 1, 2], 3, [4]); "items up and down")]
980    #[test_case(ziplist!(1, [2, 3]), ziplist!([3], 1, [2]); "items down only")]
981    #[test_case(ziplist!([1, 2], 3), ziplist!(3, [1, 2]); "items up only")]
982    #[test_case(ziplist!(1), ziplist!(1); "only focused")]
983    #[test]
984    fn rotate_down(mut s: ZipList<usize>, expected: ZipList<usize>) {
985        s.rotate_down();
986
987        assert_eq!(s, expected);
988    }
989
990    #[test_case(Position::Focus, ziplist!([1,2], 6, [3,4,5]); "focus")]
991    #[test_case(Position::Before, ziplist!([1,2,6], 3, [4,5]); "before")]
992    #[test_case(Position::After, ziplist!([1,2], 3, [6,4,5]); "after")]
993    #[test_case(Position::Head, ziplist!([6,1,2], 3, [4,5]); "head")]
994    #[test_case(Position::Tail, ziplist!([1,2], 3, [4,5,6]); "tail")]
995    #[test]
996    fn insert_at(pos: Position, expected: ZipList<usize>) {
997        let mut s = ziplist!([1, 2], 3, [4, 5]);
998        s.insert_at(pos, 6);
999
1000        assert_eq!(s, expected);
1001    }
1002}