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    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/// A position within a [ZipList].
45#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
46pub enum Position {
47    /// The current focus point
48    #[default]
49    Focus,
50    /// Above the current focus point
51    Before,
52    /// Below the current focus point
53    After,
54    /// The first element of the stack
55    Head,
56    /// The last element of the stack
57    Tail,
58}
59
60/// A [ZipList] can be thought of as a linked list with a hole punched in it to mark
61/// a single element that currently holds focus (though in practice it is implemented
62/// using a [VecDeque] for efficiency purposes). By convention, the main element is
63/// the first element in the stack (regardless of focus). Focusing operations do not
64/// reorder the elements of the stack or the resulting [Vec] that can be obtained
65/// from calling [ZipList::flatten].
66///
67/// This is a [zipper](https://en.wikipedia.org/wiki/Zipper_(data_structure))
68/// over a [VecDeque]. Many of the methods that mutate the structure of the ZipList
69/// return back a mutable reference so that they are able to be chained.
70#[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    /// Create a new ZipList specifying the focused element and and elements
94    /// above and below it.
95    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    // NOTE: Can't implement FromIterator<T> because we disallow an empty stack
113    /// For an iterator of at least one element, the first element will
114    /// be focused and all remaining elements will be placed after it.
115    /// For an empty iterator, return None.
116    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    /// The number of elements in this ZipList.
131    pub fn len(&self) -> usize {
132        self.up.len() + self.down.len() + 1
133    }
134
135    /// Always false: a ZipList always has at least one focused element.
136    pub fn is_empty(&self) -> bool {
137        false
138    }
139
140    /// Provide an iterator over this stack iterating over up,
141    /// focus and then down.
142    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    /// Provide an iterator over this stack iterating over up,
151    /// focus and then down with mutable references.
152    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    /// Iterate over the clients in this stack from the the focused element
161    /// down through the stack.
162    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    /// Flatten a ZipList into a Vector, losing the information of which
169    /// element is focused.
170    pub fn flatten(self) -> Vec<T> {
171        self.into_iter().map(|(_, t)| t).collect()
172    }
173
174    /// Return a reference to the first element in this [ZipList]
175    pub fn head(&self) -> &T {
176        self.up.back().unwrap_or(&self.focus)
177    }
178
179    /// Return a reference to the focused element in this [ZipList]
180    pub fn focused(&self) -> &T {
181        &self.focus
182    }
183
184    /// Return a reference to the last element in this [ZipList]
185    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    /// Swap the current head element with the focused element in the
194    /// stack order. Focus stays with the original focused element.
195    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    /// Rotate the ZipList until the current focused element is in the head position
210    pub fn rotate_focus_to_head(&mut self) -> &mut Self {
211        self.down.extend(self.up.drain(..).rev());
212
213        self
214    }
215
216    /// Move focus to the element in the head position
217    pub fn focus_head(&mut self) -> &mut Self {
218        let mut head = match self.up.pop_back() {
219            None => return self, // focus is already head
220            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    /// Move focus to the element in the head position
234    pub fn focus_tail(&mut self) -> &mut Self {
235        let mut tail = match self.down.pop_back() {
236            None => return self, // focus is already tail
237            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    /// Insert the given element in place of the current focus, pushing
251    /// the current focus down the [ZipList].
252    pub fn insert(&mut self, t: T) -> &mut Self {
253        self.insert_at(Position::default(), t)
254    }
255
256    /// Insert the given element at the requested position in the [ZipList].
257    /// See [Position] for the semantics of each case. For all cases, the
258    /// existing elements in the [ZipList] are pushed down to make room for
259    /// the new one.
260    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    /// Remove the focused element of this ZipList. If this was the only element then
278    /// the stack is dropped and None is returned.
279    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    /// Removed the focused element of this Ziplist.
296    ///
297    /// # Panics
298    /// Panics if the focus was the only element
299    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    /// Remove the first element that matches the given predicate function. If doing so would
311    /// remove the last element of the ZipList then `default_focus` is called to ensure that there
312    /// is a single element remaining as the current focus.
313    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    /// Map a function over all elements in this [ZipList], returning a new one.
338    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    /// Retain only elements which satisfy the given predicate. If the focused
350    /// element is removed then focus shifts to the first remaining element
351    /// after it, if there are no elements after then focus moves to the first
352    /// remaining element before. If no elements satisfy the predicate then
353    /// None is returned.
354    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    /// Reverse the ordering of a ZipList (up becomes down) while maintaining
385    /// focus.
386    #[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    /// Move focus from the current element up the stack, wrapping to the
415    /// bottom if focus is already at the top.
416    pub fn focus_up(&mut self) -> &mut Self {
417        match (self.up.is_empty(), self.down.is_empty()) {
418            // xs:x f ys   -> xs x f:ys
419            // xs:x f []   -> xs x f
420            (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            // [] f ys:y   -> f:ys y []
427            (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            // [] f []     -> [] f []
435            (true, true) => (),
436        }
437
438        self
439    }
440
441    /// Move focus from the current element down the stack, wrapping to the
442    /// top if focus is already at the bottom.
443    pub fn focus_down(&mut self) -> &mut Self {
444        match (self.up.is_empty(), self.down.is_empty()) {
445            // xs f y:ys   -> xs:f y ys
446            // [] f y:ys   -> f y ys
447            (_, 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            // x:xs f []   -> [] x xs:f
454            (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            // [] f []     -> [] f []
462            (true, true) => (),
463        }
464
465        self
466    }
467
468    /// Focus the first element found matching the given predicate function.
469    ///
470    /// Returns true if the focused element changed. If no matching elements are found,
471    /// the ZipList will be left in its original state and false is returned.
472    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    /// Focus the first element found matching the given predicate function.
487    ///
488    /// If no matching elements are found, the ZipList will be left in
489    /// its original state.
490    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    /// Swap the focused element with the one above, wrapping from top to bottom.
505    /// The currently focused element is maintained by this operation.
506    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    /// Swap the focused element with the one below, wrapping from top to bottom.
517    /// The currently focused element is maintained by this operation.
518    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    /// Rotate all elements of the stack forward, wrapping from top to bottom.
529    /// The currently focused element in the stack is maintained by this operation.
530    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    /// Rotate all elements of the stack back, wrapping from bottom to top.
541    /// The currently focused element in the stack is maintained by this operation.
542    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    /// Extract elements satisfying a predicate into a Vec, leaving remaining
555    /// elements in their original stack position.
556    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    /// Check whether a given element is in this ZipList
598    pub fn contains(&self, t: &T) -> bool {
599        &self.focus == t || self.up.contains(t) || self.down.contains(t)
600    }
601
602    /// Attempt to focus a given element in the [ZipList] if it is present.
603    ///
604    /// If the requested element is not found, the ZipList will be left in
605    /// its original state.
606    pub fn focus_element(&mut self, t: &T) {
607        self.focus_element_by(|elem| elem == t);
608    }
609
610    /// Remove an element from the stack.
611    ///
612    /// If the element was present it is returned along with the rest of the [ZipList].
613    /// If this was the last element in the stack, the stack is dropped and None is
614    /// returned.
615    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// Iteration
658
659/// An owned iterator over a [ZipList].
660#[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/// An iterator over a [ZipList].
693#[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/// A mutable iterator over a [ZipList].
722#[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        // https://github.com/rust-lang/rust-clippy/issues/14685
1044        #[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}