1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::{Generator, GeneratorResult, ValueResult};
use core::num::NonZeroUsize;
#[derive(Clone)]
pub struct SliceGenerator<'a, T> {
slice: &'a [T],
index: usize,
}
impl<'a, T> SliceGenerator<'a, T> {
#[inline]
pub fn new(slice: &'a [T]) -> Self {
Self { slice, index: 0 }
}
}
impl<'a, T> Generator for SliceGenerator<'a, T> {
type Output = &'a T;
#[inline]
fn run(&mut self, mut output: impl FnMut(Self::Output) -> ValueResult) -> GeneratorResult {
let len = self.slice.len();
while self.index < len {
if output(unsafe { self.slice.get_unchecked(self.index) }) == ValueResult::Stop {
self.index += 1;
return GeneratorResult::Stopped;
}
self.index += 1;
}
GeneratorResult::Complete
}
#[inline]
fn try_advance(&mut self, n: NonZeroUsize) -> (usize, GeneratorResult) {
let n = n.get();
let len = self.slice.len();
let available = len - self.index;
if n >= available {
self.index = len;
(available, GeneratorResult::Complete)
} else {
self.index += n;
(n, GeneratorResult::Stopped)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Generator, GeneratorExt};
use core::num::NonZeroUsize;
#[test]
fn try_advance() {
let data = [1, 2, 3, 4, 5];
let mut gen = SliceGenerator::new(&data);
let result = gen.try_advance(NonZeroUsize::new(3).unwrap());
assert_eq!(result, (3, GeneratorResult::Stopped));
assert_eq!(gen.next(), Ok(&4));
assert_eq!(gen.next(), Ok(&5));
}
#[test]
fn try_advance_inside() {
let data = [1, 2, 3, 4, 5];
let mut gen = SliceGenerator::new(&data);
assert_eq!(gen.next(), Ok(&1));
let result = gen.try_advance(NonZeroUsize::new(2).unwrap());
assert_eq!(result, (2, GeneratorResult::Stopped));
assert_eq!(gen.next(), Ok(&4));
assert_eq!(gen.next(), Ok(&5));
}
#[test]
fn try_advance_available() {
let data = [1, 2, 3, 4, 5];
let mut gen = SliceGenerator::new(&data);
let result = gen.try_advance(NonZeroUsize::new(5).unwrap());
assert_eq!(result, (5, GeneratorResult::Complete));
assert_eq!(gen.next(), Err(GeneratorResult::Complete));
}
#[test]
fn try_advance_more_than_available() {
let data = [1, 2, 3, 4, 5];
let mut gen = SliceGenerator::new(&data);
let result = gen.try_advance(NonZeroUsize::new(10).unwrap());
assert_eq!(result, (5, GeneratorResult::Complete));
assert_eq!(gen.next(), Err(GeneratorResult::Complete));
}
}