1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::protocol::Effect;
use core::{mem::MaybeUninit, ops::ControlFlow};

use crate::{
    any_trait,
    protocol::{
        visitor::{RequestHint, Sequence, SequenceScope, Status},
        walker::{Hint, HintMeta},
        ControlFlowFor, SyncEffect, Visitor,
    },
};

impl<'ctx, T: crate::Walk<'ctx>, const N: usize> crate::Walk<'ctx> for [T; N]
where
    <T as crate::Walk<'ctx>>::Walker: crate::Walker<'ctx, Effect = SyncEffect>,
{
    type Walker = Walker<'ctx, T, N, T::Walker>;
}

#[derive(Debug)]
pub struct WalkerError<E> {
    pub index: usize,
    pub error: E,
}

pub struct Walker<'ctx, T, const N: usize, W: crate::Walker<'ctx>> {
    array: [Option<T>; N],
    index: usize,
    item_err: Option<(usize, W::Error)>,
}

impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From<T>> 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<T>>
    crate::Walker<'ctx> for Walker<'ctx, T, N, W>
{
    type Effect = SyncEffect;

    type Error = WalkerError<W::Error>;

    type Output = ();

    #[inline]
    fn walk<'a>(
        mut self,
        visitor: Visitor<'a, 'ctx, Self::Effect>,
    ) -> ControlFlowFor<'a, 'ctx, Self::Effect, Self::Output, Self::Error>
    where
        Self: 'a,
    {
        if let Some(object) = visitor.upcast_mut::<dyn Sequence<'ctx, W::Effect> + '_>() {
            object.visit(&mut self);
        }

        if let Some((index, error)) = self.item_err {
            ControlFlow::Break(WalkerError { index, error })
        } else {
            ControlFlow::Continue(())
        }
    }
}

impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From<T>>
    SequenceScope<'ctx> for Walker<'ctx, T, N, W>
{
    #[inline]
    fn next<'a>(
        &'a mut self,
        visitor: Visitor<'a, 'ctx, SyncEffect>,
    ) -> ControlFlowFor<'a, 'ctx, W::Effect, Status> 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) {
            ControlFlow::Continue(_) => ControlFlow::Continue(Status::Continue),
            ControlFlow::Break(err) => {
                self.item_err = Some((self.index, err));
                ControlFlow::Continue(Status::Done)
            }
        }
    }
}