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