pub mod pyrange {
pub struct Pyrange {
start: i64,
end: i64,
step: i64,
}
impl Pyrange {
pub fn new(start: i64, end: i64, step: i64) -> Self {
Pyrange { start, end, step }
}
}
impl Iterator for Pyrange {
type Item = i64;
fn next(&mut self) -> Option<Self::Item> {
if self.step == 0 {
return None;
}
let next_value = self.start;
if (self.step > 0 && next_value >= self.end) || (self.step < 0 && next_value <= self.end) {
return None;
}
self.start += self.step;
Some(next_value)
}
}
}
#[macro_export]
macro_rules! py_range {
($start:expr) => {{
let end = $start;
let start = 0;
let step = 1;
$crate::pyrange::Pyrange::new(start, end, step)
}};
($start:expr, $end:expr) => {{
let (start, end) = if $start <= $end {
($start, $end)
} else {
($end, $start)
};
let step = 1;
$crate::pyrange::Pyrange::new(start, end, step)
}};
($start:expr, $end:expr, $step:expr) => {{
let (start, end, step) = if $step > 0 {
($start, $end, $step)
} else if $start <= $end {
($end, $start, $step)
} else {
($start, $end, $step)
};
$crate::pyrange::Pyrange::new(start, end, step)
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_py_range() {
let mut range = py_range!(0, 10, 1);
let mut values = Vec::new();
for i in &mut range {
values.push(i);
}
assert_eq!(values, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
let mut range_rev = py_range!(10, 0, -1);
let mut values_rev = Vec::new();
for i in &mut range_rev {
values_rev.push(i);
}
assert_eq!(values_rev, vec![10,9, 8, 7, 6, 5, 4, 3, 2, 1]);
}
}