1use std::{iter, num::NonZero, ops::ControlFlow, task::Poll};
2
3use o3::{
4 alloc,
5 buffer::{resident, storage},
6};
7
8use crate::{
9 Error, Nesting,
10 input::Taken,
11 segment::{
12 Admitted, Cursor, Decode, Decoder, End, Outcome, Progress,
13 input::{Input, Split},
14 },
15};
16
17pub struct Nested<'d, T: Decode<C>, C: Copy = ()> {
20 input: Input<'d>,
21 cursor: Cursor,
22 state: State<'d, T, C>,
23 context: C,
24 values: Vec<T>,
25 error: Option<Result<(), crate::parsing::Error<'d>>>,
26}
27
28enum State<'d, T: Decode<C>, C: Copy> {
29 Leading,
30 Element { end: End },
31 Group { start: usize, nesting: Nesting },
32 Projecting(Split<'d>),
33 Starting(Admitted<'d>),
34 Decoding(Box<Decoder<'d, T, C>>),
35 Delimiter,
36 Trailing,
37 Release,
38}
39
40impl<'d, T: Decode> Nested<'d, T> {
41 pub fn one(input: storage::Shared) -> crate::Result<Self> {
42 Self::new(iter::once(input))
43 }
44
45 pub fn new<I, O>(input: I) -> crate::Result<Self>
46 where
47 I: IntoIterator<Item = O>,
48 I::IntoIter: ExactSizeIterator,
49 resident::Shared<'d>: From<O>,
50 {
51 Ok(Self::with_input(Input::new(input)?, ()))
52 }
53}
54
55impl<'d, T: Decode<C>, C: Copy> Nested<'d, T, C> {
56 pub fn admitted(input: Admitted<'d>, context: C) -> Self {
57 Self::with_input(input.input, context)
58 }
59
60 fn with_input(input: Input<'d>, context: C) -> Self {
61 Self {
62 input,
63 cursor: Cursor::new(),
64 state: State::Leading,
65 values: Vec::new(),
66 context,
67 error: None,
68 }
69 }
70
71 pub fn release(&mut self, budget: &mut usize) -> Poll<()> {
72 self.error.get_or_insert(Ok(()));
73 let state = match &mut self.state {
74 State::Projecting(parts) => parts.release(budget),
75 State::Starting(input) => input.release(budget),
76 State::Decoding(worker) => worker.release(budget),
77 State::Leading
78 | State::Element { .. }
79 | State::Group { .. }
80 | State::Delimiter
81 | State::Trailing
82 | State::Release => Poll::Ready(()),
83 };
84 if state.is_pending() {
85 return Poll::Pending;
86 }
87 while let Some(value) = self.values.last_mut() {
88 if *budget == 0 || <T as Decode<C>>::release(value, budget).is_pending() {
89 return Poll::Pending;
90 }
91 if *budget == 0 {
92 return Poll::Pending;
93 }
94 drop(self.values.pop());
95 *budget -= 1;
96 }
97 self.input.release(budget).0
98 }
99
100 pub fn step(mut self, budget: NonZero<usize>) -> Outcome<'d, Self, Vec<T>> {
101 if self.error.is_some() {
102 let mut left = budget.get();
103 if self.release(&mut left).is_pending() {
104 return Outcome::Pending(self);
105 }
106 if let Some(Err(error)) = self.error {
107 return Outcome::Failed(error);
108 }
109 return Outcome::Pending(self);
110 }
111 match self.try_step(budget) {
112 Ok(ControlFlow::Continue(())) => Outcome::Pending(self),
113 Ok(ControlFlow::Break(values)) => Outcome::Ready(values),
114 Err(error) => {
115 self.error = Some(Err(error));
116 Outcome::Pending(self)
117 }
118 }
119 }
120
121 fn try_step(
122 &mut self,
123 budget: NonZero<usize>,
124 ) -> Result<ControlFlow<Vec<T>>, crate::parsing::Error<'d>> {
125 let mut left = budget.get();
126 while let Some(work) = NonZero::new(left) {
127 let input = &self.input;
128 match &mut self.state {
129 State::Leading => {
130 if self.cursor.take_ws(input) == Taken::Yes {
131 left -= 1;
132 } else {
133 if self.cursor.take(input, b'[') == Taken::No {
134 return Err(Error::Invalid.into());
135 }
136 left -= 1;
137 self.state = State::Element { end: End::Allowed };
138 }
139 }
140 State::Element { end } => {
141 if self.cursor.take_ws(input) == Taken::Yes {
142 left -= 1;
143 } else if *end == End::Allowed && self.cursor.take(input, b']') == Taken::Yes {
144 left -= 1;
145 self.state = State::Trailing;
146 } else {
147 let (byte, advance) = self.cursor.read(input).ok_or(Error::Invalid)?;
148 if !matches!(byte, b'{' | b'[') {
149 return Err(Error::Invalid.into());
150 }
151 let nesting = if input.is_admitted() {
152 Nesting::admitted()
153 } else {
154 Nesting::start(byte)?
155 };
156 let start = self.cursor.absolute;
157 self.cursor.advance(advance);
158 left -= 1;
159 self.state = State::Group { start, nesting };
160 }
161 }
162 State::Group { start, nesting } => {
163 let (byte, advance) = self.cursor.read(input).ok_or(Error::Invalid)?;
164 let done = nesting.step(byte)?;
165 self.cursor.advance(advance);
166 left -= 1;
167 if done {
168 let parts = Split::new(input, *start..self.cursor.absolute)?;
169 alloc::VecExt::try_reserve(&mut self.values, 1)
170 .map_err(Error::Allocation)?;
171 self.state = State::Projecting(parts);
172 }
173 }
174 State::Projecting(parts) => {
175 let ready = parts.step(input, &mut left)?;
176 if let Some(input) = ready {
177 self.state = State::Starting(Admitted { input });
178 }
179 }
180 State::Starting(input) => {
181 let worker = Decoder::try_admitted(input, self.context)?;
182 self.state = State::Decoding(worker);
183 }
184 State::Decoding(worker) => match worker.poll(work) {
185 Progress::NeedInput => return Err(Error::Invalid.into()),
186 Progress::Pending => return Ok(ControlFlow::Continue(())),
187 Progress::Ready(value) => {
188 (unsafe { alloc::raw::VecExt::vacancy(&mut self.values) })(value);
190 self.state = State::Delimiter;
191 return Ok(ControlFlow::Continue(()));
192 }
193 Progress::Failed(error) => return Err(error),
194 },
195 State::Delimiter => {
196 if self.cursor.take_ws(input) == Taken::Yes {
197 left -= 1;
198 } else if self.cursor.take(input, b',') == Taken::Yes {
199 left -= 1;
200 self.state = State::Element {
201 end: End::Forbidden,
202 };
203 } else if self.cursor.take(input, b']') == Taken::Yes {
204 left -= 1;
205 self.state = State::Trailing;
206 } else {
207 return Err(Error::Invalid.into());
208 }
209 }
210 State::Trailing => {
211 if self.cursor.take_ws(input) == Taken::Yes {
212 left -= 1;
213 } else if self.cursor.absolute == input.len() {
214 self.state = State::Release;
215 } else {
216 return Err(Error::Invalid.into());
217 }
218 }
219 State::Release => {
220 if self.input.release(&mut left).0.is_ready() {
221 return Ok(ControlFlow::Break(std::mem::take(&mut self.values)));
222 }
223 }
224 }
225 }
226 Ok(ControlFlow::Continue(()))
227 }
228}