beetle_iter/
lib.rs

1#[deny(missing_docs)]
2
3/// `Range<T>`'s with constant step sizes
4pub mod step_range {
5    macro_rules! declare_step_range {
6        ($name: ident, $t: ty) => {
7            /// A range with a constant step size
8            #[derive(Debug, Clone)]
9            pub struct $name<const STEP: $t> {
10                start: $t,
11                stop: $t,
12                state: $t,
13            }
14
15            impl<const STEP: $t> $name<STEP> {
16                /// Creates a new StepRange.
17                pub fn new(start: $t, stop: $t) -> Self {
18                    Self {
19                        start,
20                        stop,
21                        state: start,
22                    }
23                }
24
25                /// The start of the range
26                pub fn start(&self) -> $t {
27                    self.start
28                }
29
30                /// The end of the range
31                pub fn stop(&self) -> $t {
32                    self.stop
33                }
34            }
35
36            impl<const STEP: $t> Iterator for $name<STEP> {
37                type Item = $t;
38
39                fn next(&mut self) -> Option<Self::Item> {
40                    if self.state <= self.stop {
41                        let current_state = self.state;
42                        self.state += STEP;
43                        Some(current_state)
44                    } else {
45                        None
46                    }
47                }
48            }
49        };
50    }
51
52    declare_step_range!(StepRangeU8, u8);
53    declare_step_range!(StepRangeU16, u16);
54    declare_step_range!(StepRangeU32, u32);
55    declare_step_range!(StepRangeU64, u64);
56    declare_step_range!(StepRangeU128, u128);
57    declare_step_range!(StepRangeUSize, usize);
58    declare_step_range!(StepRangeI8, i8);
59    declare_step_range!(StepRangeI16, i16);
60    declare_step_range!(StepRangeI32, i32);
61    declare_step_range!(StepRangeI64, i64);
62    declare_step_range!(StepRangeI128, i128);
63    declare_step_range!(StepRangeISize, isize);
64}
65
66#[cfg(test)]
67mod tests {
68
69    #[test]
70    fn readme_step_range_examples() {
71        use crate::step_range::StepRangeU64;
72
73        // The odd positive integers from 1 to 1000 the traditional way.
74        let odd_numbers_std = (1..1000).step_by(2);
75
76        // The odd positive integers from 1 to 1000 with a constant step size.
77        let odd_numbers = StepRangeU64::<2>::new(1, 1000);
78
79        let ans = odd_numbers.zip(odd_numbers_std).all(|(a, b)| a == b);
80        assert!(ans);
81    }
82}