Skip to main content

deser_value/
de.rs

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
10/// Containers are not preallocated beyond this number of elements as the
11/// length comes from the input.
12const MAX_PREALLOC: usize = 1024;
13
14/// Where a [`ValueSink`] places the value.
15enum Out<'a> {
16    Value(&'a mut Option<Value>),
17    Seq(&'a mut Option<Seq>),
18    Map(&'a mut Option<Map>),
19    /// Updates a value: maps are merged into maps, everything else replaces
20    /// the value.
21    UpdateValue(&'a mut Value),
22    /// Merges a map into a map.
23    UpdateMap(&'a mut Map),
24}
25
26/// The container a [`ValueSink`] is building.
27enum Building {
28    None,
29    Seq(Seq),
30    Map(Map),
31}
32
33/// What happens to the value of an entry of a map.
34#[derive(Default)]
35enum Entry {
36    /// The entry is inserted, it replaces the value of a key that was given
37    /// before.
38    #[default]
39    Insert,
40    /// The value is added to the values of a key of a multimap that was
41    /// given before.
42    Repeat,
43    /// The value is dropped as the key was given before and the first value
44    /// is used.
45    Ignore,
46}
47
48/// Deserializes values.
49struct ValueSink<'a> {
50    out: Out<'a>,
51    building: Building,
52    meta: Option<Box<Meta>>,
53    // the key of the entry whose value is deserialized.
54    key: Option<Value>,
55    // the key or value that is deserialized.
56    slot: Option<Value>,
57    // what happens to the value of the current entry
58    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    /// Adds the key or value that was deserialized last to the container.
74    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    /// Prepares for the next value in the container.
95    ///
96    /// A key that was given before collects the values in a multimap,
97    /// otherwise the [`DuplicateKeys`] policy decides.
98    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
124/// Merges the entries of a map into another map.
125///
126/// The values of keys that exist are replaced (not merged), the entries keep
127/// their position.  New entries are added at the end.  Keys in `map` are
128/// unique, so the entries it adds cannot collide with each other.
129fn 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/// Adds the value of a key of a multimap that was given before.
142///
143/// The values of the key become a sequence that is marked as repeated.
144#[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    // point at the key if its location is known
165    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    /// Takes all keys when the value is flattened into a struct.
258    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            // a value that is flattened into a struct is an empty map if no
279            // key was left for it
280            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                // updates keep the value
290                _ => 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            // maps are merged into maps (the value keeps its meta data),
311            // everything else is replaced
312            (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
336/// Captures the meta data of the current event.
337fn 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
349/// Converts an atom into a value.
350fn 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    /// Updates the value: a map merges the data into it if it's a map (the
401    /// values of keys that exist are replaced), all other values are
402    /// replaced.
403    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    /// Merges the data into the map, the values of keys that exist are
426    /// replaced.
427    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}