Diffstat (limited to 'src/impls/core/iterator.rs')
| -rw-r--r-- | src/impls/core/iterator.rs | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/src/impls/core/iterator.rs b/src/impls/core/iterator.rs index 1bd39b6..cdcd71b 100644 --- a/src/impls/core/iterator.rs +++ b/src/impls/core/iterator.rs @@ -1,49 +1,76 @@ -use crate::{Walker, ControlFlow, walk::WalkOnce, protocol::lookup_visit, protocols::sequence}; +use crate::protocol::ImplementerExt; +use crate::protocols::{sequence, ControlFlow}; +use crate::walk::WalkOnce; -pub struct IterWalker<I> { +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<I> IterWalker<I>{ +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() + iter: iter.into_iter(), + err: None, } } } -impl<'ctx, I> Walker<'ctx> for IterWalker<I> +impl<'ctx, I> WalkOnce<'ctx> for IterWalker<'ctx, I> where I: Iterator, - <I as Iterator>::Item: WalkOnce<'ctx> + <I as Iterator>::Item: WalkOnce<'ctx>, { - fn walk(&mut self, visitor: &mut dyn crate::Visitor<'ctx>) -> ControlFlow { - match lookup_visit::<sequence::Sequence, _>(visitor) { - Ok(visit) => { - visit.visit(self).to_done() - }, - Err(err) => { - ControlFlow::Error - }, + 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<I> +impl<'ctx, I> sequence::Accessor<'ctx> for IterWalker<'ctx, I> where I: Iterator, - <I as Iterator>::Item: WalkOnce<'ctx> + <I as Iterator>::Item: WalkOnce<'ctx>, { - fn next(&mut self, visitor: &mut dyn crate::Visitor<'ctx>) -> ControlFlow { - if let Some(value) = self.iter.next() { - match value.walk_once(visitor) { - Ok(_) => ControlFlow::Continue, + 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) => { - ControlFlow::Error - }, + self.err = Some(err); + sequence::ControlFlow::Error + } } } else { - ControlFlow::Done + sequence::ControlFlow::Done } } } |