use crate::runtime::Variant;
use crate::runtime::gc::GcTrace;
use crate::runtime::errors::{ExecResult};
pub struct IterState {
iter: Variant,
state: Variant,
}
unsafe impl GcTrace for IterState {
fn trace(&self) {
self.iter.trace();
self.state.trace();
}
}
impl IterState {
pub fn new(iter: Variant, state: Variant) -> Self {
Self { iter, state }
}
#[inline]
pub fn get_iter(&self) -> &Variant { &self.iter }
#[inline]
pub fn get_state(&self) -> &Variant { &self.state }
#[inline]
pub fn has_value(&self) -> ExecResult<bool> {
self.state.as_bool()
}
#[inline]
pub fn get_value(&self) -> ExecResult<Variant> {
self.iter.iter_get(&self.state)
}
#[inline]
pub fn next_state(&self) -> ExecResult<Variant> {
self.iter.iter_next(&self.state)
}
#[inline]
pub fn next(&self) -> ExecResult<IterState> {
Ok(Self {
iter: self.iter,
state: self.next_state()?,
})
}
#[inline]
pub fn advance(&mut self) -> ExecResult<()> {
self.state = self.iter.iter_next(&self.state)?;
Ok(())
}
}
impl IntoIterator for IterState {
type Item = ExecResult<Variant>;
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter {
Iter(self)
}
}
pub struct Iter(IterState);
impl Iter {
fn next_value(&mut self) -> ExecResult<Option<Variant>> {
if !self.0.has_value()? {
return Ok(None)
}
let next = self.0.get_value()?;
self.0.advance()?;
Ok(Some(next))
}
}
impl Iterator for Iter {
type Item = ExecResult<Variant>;
fn next(&mut self) -> Option<Self::Item> {
match self.next_value() {
Ok(None) => None,
Ok(Some(value)) => Some(Ok(value)),
Err(error) => Some(Err(error)),
}
}
}