1pub mod pyrange {
2 pub struct Pyrange {
3 start: i64,
4 end: i64,
5 step: i64,
6 }
7
8 impl Pyrange {
9 pub fn new(start: i64, end: i64, step: i64) -> Self {
10 Pyrange { start, end, step }
11 }
12 }
13
14
15 impl Iterator for Pyrange {
16 type Item = i64;
17
18 fn next(&mut self) -> Option<Self::Item> {
19 if self.step == 0 {
20 return None;
21 }
22
23 let next_value = self.start;
24 if (self.step > 0 && next_value >= self.end) || (self.step < 0 && next_value <= self.end) {
25 return None;
26 }
27
28 self.start += self.step;
29 Some(next_value)
30 }
31 }
32}
33
34#[macro_export]
35macro_rules! py_range {
36 ($start:expr) => {{
37 let end = $start;
38 let start = 0;
39 let step = 1;
40 $crate::pyrange::Pyrange::new(start, end, step)
41 }};
42 ($start:expr, $end:expr) => {{
43 let (start, end) = if $start <= $end {
44 ($start, $end)
45 } else {
46 ($end, $start)
47 };
48 let step = 1;
49 $crate::pyrange::Pyrange::new(start, end, step)
50 }};
51 ($start:expr, $end:expr, $step:expr) => {{
52 let (start, end, step) = if $step > 0 {
53 ($start, $end, $step)
54 } else if $start <= $end {
55 ($end, $start, $step)
56 } else {
57 ($start, $end, $step)
58 };
59 $crate::pyrange::Pyrange::new(start, end, step)
60 }};
61}
62
63
64
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_py_range() {
72 let mut range = py_range!(0, 10, 1);
74
75 let mut values = Vec::new();
77 for i in &mut range {
78 values.push(i);
79 }
80 assert_eq!(values, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
81
82
83
84
85 let mut range_rev = py_range!(10, 0, -1);
87
88 let mut values_rev = Vec::new();
90 for i in &mut range_rev {
91 values_rev.push(i);
92 }
93 assert_eq!(values_rev, vec![10,9, 8, 7, 6, 5, 4, 3, 2, 1]);
94
95
96 }
97}
98
99