use crate::protocol::ImplementerExt;
use crate::protocols::{sequence, ControlFlow};
use crate::walk::WalkOnce;
pub struct IterWalker<'ctx, I>
where
I: Iterator,
<I as Iterator>::Item: WalkOnce<'ctx>,
{
iter: I,
err: Option<<<I as Iterator>::Item as WalkOnce<'ctx>>::Error>,
}
impl<'ctx, I> IterWalker<'ctx, I>
where
I: Iterator,
<I as Iterator>::Item: WalkOnce<'ctx>,
{
pub fn new<T: IntoIterator<IntoIter = I>>(iter: T) -> Self {
Self {
iter: iter.into_iter(),
err: None,
}
}
}
impl<'ctx, I> WalkOnce<'ctx> for IterWalker<'ctx, I>
where
I: Iterator,
<I as Iterator>::Item: WalkOnce<'ctx>,
{
type Error = <<I as Iterator>::Item as WalkOnce<'ctx>>::Error;
type Value = ();
#[inline]
fn walk_once(
mut self,
visitor: &mut dyn crate::protocol::Implementer<'ctx>,
) -> Result<Self::Value, Self::Error> {
if let Some(interface) = visitor.interface_for::<sequence::Sequence>() {
match interface.as_object().visit(&mut self) {
ControlFlow::Done => Ok(()),
ControlFlow::Error => match self.err {
Some(err) => Err(err),
None => Ok(()),
},
}
} else {
Ok(())
}
}
}
impl<'ctx, I> sequence::Accessor<'ctx> for IterWalker<'ctx, I>
where
I: Iterator,
<I as Iterator>::Item: WalkOnce<'ctx>,
{
fn next(
&mut self,
visitor: &mut dyn crate::protocol::Implementer<'ctx>,
) -> sequence::ControlFlow {
if let Some(item) = self.iter.next() {
match item.walk_once(visitor) {
Ok(_) => sequence::ControlFlow::Continue,
Err(err) => {
self.err = Some(err);
sequence::ControlFlow::Error
}
}
} else {
sequence::ControlFlow::Done
}
}
}