use num_traits::One;
use std::{fmt::Display, ops::Add};
use leo_ast::Value;
use leo_errors::LeoError;
pub(crate) trait LoopBound:
Add<Output = Self> + Copy + Display + One + PartialOrd + TryFrom<Value, Error = LeoError>
{
}
impl LoopBound for i128 {}
impl LoopBound for u128 {}
pub(crate) enum Clusivity {
Inclusive,
Exclusive,
}
pub(crate) struct RangeIterator<I: LoopBound> {
end: I,
current: Option<I>,
clusivity: Clusivity,
}
impl<I: LoopBound> RangeIterator<I> {
pub(crate) fn new(start: I, end: I, clusivity: Clusivity) -> Self {
Self { end, current: Some(start), clusivity }
}
}
impl<I: LoopBound> Iterator for RangeIterator<I> {
type Item = I;
fn next(&mut self) -> Option<Self::Item> {
match self.current {
None => None,
Some(value) if value < self.end => {
self.current = Some(value.add(I::one()));
Some(value)
}
Some(value) => {
self.current = None;
match self.clusivity {
Clusivity::Exclusive => None,
Clusivity::Inclusive => Some(value),
}
}
}
}
}