use core::{mem::MaybeUninit, ops::ControlFlow}; use crate::{ any_trait, }; impl<'ctx, T: crate::Walk<'ctx>, const N: usize> crate::Walk<'ctx> for [T; N] where >::Walker: crate::Walker<'ctx, Effect = SyncEffect>, { type Walker = Walker<'ctx, T, N, T::Walker>; } #[derive(Debug)] pub struct WalkerError { pub index: usize, pub error: E, } pub struct Walker<'ctx, T, const N: usize, W: crate::Walker<'ctx>> { array: [Option; N], index: usize, item_err: Option<(usize, W::Error)>, } impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From> From<[T; N]> for Walker<'ctx, T, N, W> { fn from(value: [T; N]) -> Self { Self { array: value.map(Some), index: 0, item_err: None, } } } impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From> crate::Walker<'ctx> for Walker<'ctx, T, N, W> { type Effect = SyncEffect; type Error = WalkerError; type Output = (); #[inline] fn walk<'a>( mut self, visitor: Visitor<'a, 'ctx, Self::Effect>, ) -> Yield<'a, 'ctx, Result, Self::Effect> where Self: 'a, { if let Some(object) = visitor.upcast_mut:: + '_>() { object.visit(&mut self); } if let Some((index, error)) = self.item_err { Err(WalkerError { index, error }) } else { Ok(()) } } } impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From> SequenceScope<'ctx, SyncEffect> for Walker<'ctx, T, N, W> { #[inline] fn next<'a>( &'a mut self, visitor: Visitor<'a, 'ctx, SyncEffect>, ) -> Yield<'a, 'ctx, ControlFlow<(), Status>, W::Effect> where 'ctx: 'a, { if self.index >= N { return ControlFlow::Continue(Status::Done); } let value = unsafe { self.array .get_unchecked_mut(self.index) .take() .unwrap_unchecked() }; self.index += 1; let walker = W::from(value); match walker.walk(visitor) { Ok(_) => ControlFlow::Continue(Status::Continue), Err(err) => { self.item_err = Some((self.index, err)); ControlFlow::Continue(Status::Done) } } } }