Diffstat (limited to 'src/impls/core/iterator.rs')
-rw-r--r--src/impls/core/iterator.rs73
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
}
}
}