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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
pub mod recoverable {
    use crate::{error::UniError, protocol::Protocol, Visitor};

    pub trait Accessor<'value, 'ctx: 'value, WalkerErr, VisitorErr> {
        /// Each time this is called the walker resets.
        fn walk_new(
            &mut self,
            visitor: &mut dyn Visitor<'value, 'ctx, WalkerErr, Error = VisitorErr>,
        ) -> Result<(), UniError<WalkerErr, VisitorErr>>;
    }

    pub enum Recoverable {}

    impl Protocol for Recoverable {
        type Hint<'value, 'ctx: 'value> = ();

        type Known<'value, 'ctx: 'value> = ();

        type Accessor<
            'walking,
            'value: 'walking,
            'ctx: 'value,
            WalkerErr: 'value,
            VisitorErr: 'value,
        > = &'walking mut dyn Accessor<'value, 'ctx, WalkerErr, VisitorErr>;
    }
}

pub mod sequence {
    use crate::{error::UniError, protocol::Protocol, Visitor};

    pub struct Hint {
        pub min_len: Option<usize>,
        pub max_len: Option<usize>,
    }

    pub struct Known {
        pub len: Option<usize>,
    }

    pub trait Accessor<'value, 'ctx: 'value, WalkerErr, VisitorErr> {
        fn next(
            &mut self,
            visitor: &mut dyn Visitor<'value, 'ctx, WalkerErr, Error = VisitorErr>,
        ) -> Result<(), UniError<WalkerErr, VisitorErr>>;
    }

    pub enum Sequence {}

    impl Protocol for Sequence {
        type Hint<'value, 'ctx: 'value> = Hint;

        type Known<'value, 'ctx: 'value> = Known;

        type Accessor<
            'walking,
            'value: 'walking,
            'ctx: 'value,
            WalkerErr: 'value,
            VisitorErr: 'value,
        > = &'walking mut dyn Accessor<'value, 'ctx, WalkerErr, VisitorErr>;
    }
}

pub mod reference {
    use core::{any::Any, marker::PhantomData};

    use crate::protocol::Protocol;

    pub enum Kind {
        Walking,
        Value,
        Context,
        Static,
    }

    pub struct Hint {
        pub kind: Option<Kind>,

        pub min_len: Option<usize>,
        pub max_len: Option<usize>,
    }

    pub struct Known {
        pub kind: Option<Kind>,

        /// For dynamically sized types.
        pub len: Option<usize>,
    }

    pub enum Ref<'walking, 'value: 'walking, 'ctx: 'value, T: ?Sized + 'static> {
        Walking(&'walking T),
        Value(&'value T),
        Context(&'ctx T),
        Static(&'static T),
    }

    pub enum Mut<'walking, 'value: 'walking, 'ctx: 'value, T: ?Sized + 'static> {
        Walking(&'walking mut T),
        Value(&'value mut T),
        Context(&'ctx mut T),
        Static(&'static mut T),
    }

    pub struct Reference<T: ?Sized + Any>(PhantomData<fn() -> T>);

    pub struct ReferenceMut<T: ?Sized + Any>(PhantomData<fn() -> T>);

    impl<T: ?Sized + Any> Protocol for Reference<T> {
        type Hint<'value, 'ctx: 'value> = Hint;

        type Known<'value, 'ctx: 'value> = Known;

        type Accessor<
            'walking,
            'value: 'walking,
            'ctx: 'value,
            WalkerErr: 'value,
            VisitorErr: 'value,
        > = Ref<'walking, 'value, 'ctx, T>;
    }

    impl<T: ?Sized + Any> Protocol for ReferenceMut<T> {
        type Hint<'value, 'ctx: 'value> = Hint;

        type Known<'value, 'ctx: 'value> = Known;

        type Accessor<
            'walking,
            'value: 'walking,
            'ctx: 'value,
            WalkerErr: 'value,
            VisitorErr: 'value,
        > = Mut<'walking, 'value, 'ctx, T>;
    }
}