Skip to main content

jpreprocess_window/
lib.rs

1//! An iterator-like object which returns contiguous windows containing five mutable references.
2//!
3//! ## Example
4//! ```rust
5//! use jpreprocess_window::*;
6//!
7//! let mut vector = [0, 1, 2, 3, 4];
8//! let mut iter = IterQuintMut::new(&mut vector);
9//! assert_eq!(iter.next().unwrap(), Quintuple::First(&mut 0, &mut 1, &mut 2, &mut 3));
10//! assert_eq!(iter.next().unwrap(), Quintuple::Full(&mut 0, &mut 1, &mut 2, &mut 3, &mut 4));
11//! assert_eq!(iter.next().unwrap(), Quintuple::ThreeLeft(&mut 1, &mut 2, &mut 3, &mut 4));
12//! assert_eq!(iter.next().unwrap(), Quintuple::TwoLeft(&mut 2, &mut 3, &mut 4));
13//! assert_eq!(iter.next().unwrap(), Quintuple::Last(&mut 3, &mut 4));
14//! ```
15
16#![cfg_attr(docsrs, feature(doc_cfg))]
17
18pub mod structures;
19pub use structures::*;
20
21pub trait IterQuintMutTrait {
22    type Item;
23    fn iter_quint_mut(&mut self) -> IterQuintMut<'_, Self::Item>;
24    fn iter_quint_mut_range(&mut self, start: usize, end: usize) -> IterQuintMut<'_, Self::Item>;
25}
26
27pub struct IterQuintMut<'a, T> {
28    vec: &'a mut [T],
29    target: usize,
30}
31
32impl<'a, T> IterQuintMut<'a, T> {
33    pub fn new(vec: &'a mut [T]) -> Self {
34        Self { vec, target: 0 }
35    }
36
37    // This method cannot be converted into trait because of the mutable references
38    #[allow(clippy::should_implement_trait)]
39    pub fn next(&mut self) -> Option<Quintuple<&mut T>> {
40        let next = Self::next_iter(self.target, self.vec);
41        self.target += 1;
42        next
43    }
44
45    fn next_iter(target: usize, vec: &mut [T]) -> Option<Quintuple<&mut T>> {
46        use Quintuple::*;
47        match (vec.len(), target) {
48            (0, _) => None,
49            (1, 0) => vec.first_mut().map(Single),
50            (1, _) => None,
51            (2, 0) => {
52                let [i0, i1] = &mut vec[0..2] else {
53                    unreachable!()
54                };
55                Some(Double(i0, i1))
56            }
57            (3, 0) => {
58                let [i0, i1, i2] = &mut vec[0..3] else {
59                    unreachable!()
60                };
61                Some(Triple(i0, i1, i2))
62            }
63            (_, 0) => {
64                let [i0, i1, i2, i3] = &mut vec[0..4] else {
65                    unreachable!()
66                };
67                Some(First(i0, i1, i2, i3))
68            }
69            (_, t) => match &mut vec[t - 1..] {
70                [i0, i1, i2, i3, i4, ..] => Some(Full(i0, i1, i2, i3, i4)),
71                [i0, i1, i2, i3] => Some(ThreeLeft(i0, i1, i2, i3)),
72                [i0, i1, i2] => Some(TwoLeft(i0, i1, i2)),
73                [i0, i1] => Some(Last(i0, i1)),
74                [_] => None,
75                _ => unreachable!(),
76            },
77        }
78    }
79}