1use std::borrow::Cow;
2
3use deser_core::de::{Deserialize, DuplicateKeys, Sink, SinkHandle};
4use deser_core::{Atom, Error, ErrorKind, Source, State};
5
6use crate::map::Map;
7use crate::seq::Seq;
8use crate::value::{Kind, Meta, Span, Value, owned_bytes};
9
10const MAX_PREALLOC: usize = 1024;
13
14enum Out<'a> {
16 Value(&'a mut Option<Value>),
17 Seq(&'a mut Option<Seq>),
18 Map(&'a mut Option<Map>),
19 UpdateValue(&'a mut Value),
22 UpdateMap(&'a mut Map),
24}
25
26enum Building {
28 None,
29 Seq(Seq),
30 Map(Map),
31}
32
33#[derive(Default)]
35enum Entry {
36 #[default]
39 Insert,
40 Repeat,
43 Ignore,
46}
47
48struct ValueSink<'a> {
50 out: Out<'a>,
51 building: Building,
52 meta: Option<Box<Meta>>,
53 key: Option<Value>,
55 slot: Option<Value>,
57 entry: Entry,
59}
60
61impl<'a> ValueSink<'a> {
62 fn new(out: Out<'a>) -> ValueSink<'a> {
63 ValueSink {
64 out,
65 building: Building::None,
66 meta: None,
67 key: None,
68 slot: None,
69 entry: Entry::Insert,
70 }
71 }
72
73 fn flush(&mut self) {
75 if let Some(value) = self.slot.take() {
76 match self.building {
77 Building::Seq(ref mut seq) => seq.items.push(value),
78 Building::Map(ref mut map) => {
79 if let Some(key) = self.key.take() {
80 match std::mem::take(&mut self.entry) {
81 Entry::Insert => {
82 map.inner.entries.insert(key, value);
83 }
84 Entry::Repeat => add_repeated(map, &key, value),
85 Entry::Ignore => {}
86 }
87 }
88 }
89 Building::None => {}
90 }
91 }
92 }
93
94 fn begin_value(&mut self, state: &State) -> Result<(), Error> {
99 match self.building {
100 Building::Map(ref map) => {
101 let key = self
102 .slot
103 .take()
104 .ok_or_else(|| Error::new(ErrorKind::Unexpected, "missing map key"))?;
105 if map.contains_key(&key) {
106 self.entry = if map.is_multimap() {
107 Entry::Repeat
108 } else {
109 match DuplicateKeys::of(state) {
110 DuplicateKeys::Last => Entry::Insert,
111 DuplicateKeys::First => Entry::Ignore,
112 _ => return Err(duplicate_key(&key)),
113 }
114 };
115 }
116 self.key = Some(key);
117 }
118 _ => self.flush(),
119 }
120 Ok(())
121 }
122}
123
124fn merge_map(target: &mut Map, mut map: Map) {
130 if target.is_empty() {
131 *target = map;
132 return;
133 }
134 let entries = &mut target.inner.entries;
135 entries.reserve(map.len());
136 for (key, value) in std::mem::take(&mut map.inner.entries) {
137 entries.insert(key, value);
138 }
139}
140
141#[cold]
145fn add_repeated(map: &mut Map, key: &Value, value: Value) {
146 let Some(existing) = map.inner.entries.get_mut(key) else {
147 return;
148 };
149 match existing.kind {
150 Kind::Seq(ref mut seq) if seq.is_repeated() => seq.items.push(value),
151 _ => {
152 let first = std::mem::replace(existing, Value::from(()));
153 *existing = Value::from(Seq::from(vec![first, value]).with_repeated(true));
154 }
155 }
156}
157
158#[cold]
159fn duplicate_key(key: &Value) -> Error {
160 let err = Error::new(
161 ErrorKind::Unexpected,
162 format!("duplicate map key {:?}", key),
163 );
164 match key.span() {
166 Some(span) => err.with_offset(span.range().start),
167 None => err,
168 }
169}
170
171impl<'a, 'de> Sink<'de> for ValueSink<'a> {
172 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
173 match self.out {
174 Out::Value(ref mut out) => {
175 **out = Some(atom_value(atom, state)?);
176 Ok(())
177 }
178 Out::UpdateValue(ref mut out) => {
179 **out = atom_value(atom, state)?;
180 Ok(())
181 }
182 _ => self.unexpected_atom(atom, state),
183 }
184 }
185
186 fn map(&mut self, state: &mut State) -> Result<(), Error> {
187 if let Out::Seq(_) = self.out {
188 return Err(Error::new(
189 ErrorKind::Unexpected,
190 "unexpected map, expected sequence",
191 ));
192 }
193 let shape = state.container_shape();
194 self.meta = capture_meta(state);
195 self.building = Building::Map(
196 Map::with_capacity(shape.len().unwrap_or(0).min(MAX_PREALLOC))
197 .with_order(shape.order())
198 .with_multimap(shape.is_multimap()),
199 );
200 Ok(())
201 }
202
203 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
204 if let Out::Map(_) | Out::UpdateMap(_) = self.out {
205 return Err(Error::new(
206 ErrorKind::Unexpected,
207 "unexpected sequence, expected map",
208 ));
209 }
210 let shape = state.container_shape();
211 self.meta = capture_meta(state);
212 self.building = Building::Seq(
213 Seq::with_capacity(shape.len().unwrap_or(0).min(MAX_PREALLOC))
214 .with_order(shape.order()),
215 );
216 Ok(())
217 }
218
219 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
220 self.flush();
221 Ok(Value::deserialize_into(&mut self.slot, state))
222 }
223
224 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
225 self.begin_value(state)?;
226 Ok(Value::deserialize_into(&mut self.slot, state))
227 }
228
229 fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
230 self.flush();
231 self.slot = Some(atom_value(atom, state)?);
232 Ok(())
233 }
234
235 fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
236 self.begin_value(state)?;
237 self.slot = Some(atom_value(atom, state)?);
238 Ok(())
239 }
240
241 fn __private_borrowed_key_atom(
242 &mut self,
243 atom: Atom<'de>,
244 state: &mut State,
245 ) -> Result<(), Error> {
246 self.__private_key_atom(atom, state)
247 }
248
249 fn __private_borrowed_value_atom(
250 &mut self,
251 atom: Atom<'de>,
252 state: &mut State,
253 ) -> Result<(), Error> {
254 self.__private_value_atom(atom, state)
255 }
256
257 fn value_for_key(
259 &mut self,
260 key: &str,
261 state: &mut State,
262 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
263 match self.building {
264 Building::Map(_) => self.flush(),
265 Building::None if !matches!(self.out, Out::Seq(_)) => {
266 self.building = Building::Map(Map::new().with_multimap(state.is_multimap()));
267 }
268 _ => return Ok(None),
269 }
270 self.slot = Some(Value::from(key));
271 self.begin_value(state)?;
272 Ok(Some(Value::deserialize_into(&mut self.slot, state)))
273 }
274
275 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
276 self.flush();
277 let kind = match std::mem::replace(&mut self.building, Building::None) {
278 Building::None => match self.out {
281 Out::Value(ref mut out @ None) => {
282 **out = Some(Value::from(Map::new()));
283 return Ok(());
284 }
285 Out::Map(ref mut out @ None) => {
286 **out = Some(Map::new());
287 return Ok(());
288 }
289 _ => return Ok(()),
291 },
292 Building::Seq(seq) => Kind::Seq(seq),
293 Building::Map(map) => Kind::Map(map),
294 };
295 if let Some(ref mut meta) = self.meta
296 && let Some(span) = meta.span_mut()
297 && let Some(range) = state.input_range()
298 {
299 span.set_end(range.start, range.end);
300 }
301 match (&mut self.out, kind) {
302 (Out::Value(out), kind) => {
303 **out = Some(Value {
304 kind,
305 meta: self.meta.take(),
306 })
307 }
308 (Out::Seq(out), Kind::Seq(seq)) => **out = Some(seq),
309 (Out::Map(out), Kind::Map(map)) => **out = Some(map),
310 (Out::UpdateValue(out), kind) => match (&mut out.kind, kind) {
313 (Kind::Map(target), Kind::Map(map)) => merge_map(target, map),
314 (_, kind) => {
315 **out = Value {
316 kind,
317 meta: self.meta.take(),
318 }
319 }
320 },
321 (Out::UpdateMap(out), Kind::Map(map)) => merge_map(out, map),
322 _ => unreachable!(),
323 }
324 Ok(())
325 }
326
327 fn expecting(&self) -> Cow<'_, str> {
328 Cow::Borrowed(match self.out {
329 Out::Value(_) | Out::UpdateValue(_) => "any value",
330 Out::Seq(_) => "sequence",
331 Out::Map(_) | Out::UpdateMap(_) => "map",
332 })
333 }
334}
335
336fn capture_meta(state: &State) -> Option<Box<Meta>> {
338 let span = match (state.input_range(), state.get::<Source>()) {
339 (Some(range), Some(source)) => Some(Span::new(range, source.0.clone())),
340 _ => None,
341 };
342 let event_data = state.capture_event_data();
343 if span.is_none() && event_data.is_empty() {
344 return None;
345 }
346 Some(Box::new(Meta::from_parts(event_data, span)))
347}
348
349fn atom_value(atom: Atom, state: &State) -> Result<Value, Error> {
351 let kind = match atom {
352 Atom::Null => Kind::Null,
353 Atom::Bool(value) => Kind::Bool(value),
354 Atom::Str(value) => Kind::Str(value.into_owned()),
355 Atom::Lexical(value) => Kind::Lexical(value.into_owned()),
356 Atom::Bytes(value) => Kind::Bytes(owned_bytes(value)),
357 Atom::Char(value) => Kind::Char(value),
358 Atom::U64(value) => Kind::U64(value),
359 Atom::I64(value) => Kind::from_i64(value),
360 Atom::F32(value) => Kind::F32(value),
361 Atom::F64(value) => Kind::F64(value),
362 Atom::Ext(value) => Kind::from_ext(value),
363 Atom::Implicit(value) => Kind::Implicit(value.to_static()),
364 other => return Err(other.unexpected_error("any value")),
365 };
366 Ok(Value {
367 kind,
368 meta: capture_meta(state),
369 })
370}
371
372impl<'de> Deserialize<'de> for Value {
373 fn deserialize_into<'out>(
374 out: &'out mut Option<Self>,
375 state: &mut State,
376 ) -> SinkHandle<'out, 'de> {
377 SinkHandle::arena(ValueSink::new(Out::Value(out)), state)
378 }
379
380 #[doc(hidden)]
381 fn __private_atom_into(
382 out: &mut Option<Self>,
383 atom: Atom,
384 state: &mut State,
385 ) -> Result<(), Error> {
386 *out = Some(atom_value(atom, state)?);
387 Ok(())
388 }
389
390 #[doc(hidden)]
391 fn __private_borrowed_atom_into(
392 out: &mut Option<Self>,
393 atom: Atom<'de>,
394 state: &mut State,
395 ) -> Result<(), Error> {
396 *out = Some(atom_value(atom, state)?);
397 Ok(())
398 }
399
400 fn deserialize_update<'out>(value: &'out mut Self, state: &mut State) -> SinkHandle<'out, 'de> {
404 SinkHandle::arena(ValueSink::new(Out::UpdateValue(value)), state)
405 }
406}
407
408impl<'de> Deserialize<'de> for Seq {
409 fn deserialize_into<'out>(
410 out: &'out mut Option<Self>,
411 state: &mut State,
412 ) -> SinkHandle<'out, 'de> {
413 SinkHandle::arena(ValueSink::new(Out::Seq(out)), state)
414 }
415}
416
417impl<'de> Deserialize<'de> for Map {
418 fn deserialize_into<'out>(
419 out: &'out mut Option<Self>,
420 state: &mut State,
421 ) -> SinkHandle<'out, 'de> {
422 SinkHandle::arena(ValueSink::new(Out::Map(out)), state)
423 }
424
425 fn deserialize_update<'out>(value: &'out mut Self, state: &mut State) -> SinkHandle<'out, 'de> {
428 SinkHandle::arena(ValueSink::new(Out::UpdateMap(value)), state)
429 }
430}