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