Skip to main content

deser_value/
de.rs

1use std::borrow::Cow;
2
3use deser_core::de::{Deserialize, DuplicateKeys, Sink, SinkHandle, default_atom};
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/// Where a [`ValueSink`] places the value.
11enum Out<'a> {
12    Value(&'a mut Option<Value>),
13    Seq(&'a mut Option<Seq>),
14    Map(&'a mut Option<Map>),
15    /// Updates a value: maps are merged into maps (empty sequences that can
16    /// be maps leave them as they are), everything else replaces
17    /// the value.
18    UpdateValue(&'a mut Value),
19    /// Merges a map into a map.
20    UpdateMap(&'a mut Map),
21}
22
23/// The container a [`ValueSink`] is building.
24enum Building {
25    None,
26    Seq(Seq),
27    Map(Map),
28}
29
30/// What happens to the value of an entry of a map.
31#[derive(Default)]
32enum Entry {
33    /// The entry is inserted, it replaces the value of a key that was given
34    /// before.
35    #[default]
36    Insert,
37    /// The value is added to the values of a key of a multimap that was
38    /// given before.
39    Repeat,
40    /// The value is dropped as the key was given before and the first value
41    /// is used.
42    Ignore,
43}
44
45/// Deserializes values.
46struct ValueSink<'a> {
47    out: Out<'a>,
48    building: Building,
49    meta: Option<Box<Meta>>,
50    // the key of the entry whose value is deserialized.
51    key: Option<Value>,
52    // the key or value that is deserialized.
53    slot: Option<Value>,
54    // what happens to the value of the current entry
55    entry: Entry,
56}
57
58impl<'a> ValueSink<'a> {
59    fn new(out: Out<'a>) -> ValueSink<'a> {
60        ValueSink {
61            out,
62            building: Building::None,
63            meta: None,
64            key: None,
65            slot: None,
66            entry: Entry::Insert,
67        }
68    }
69
70    /// Adds the key or value that was deserialized last to the container.
71    fn flush(&mut self) {
72        if let Some(value) = self.slot.take() {
73            match self.building {
74                Building::Seq(ref mut seq) => seq.items.push(value),
75                Building::Map(ref mut map) => {
76                    if let Some(key) = self.key.take() {
77                        match std::mem::take(&mut self.entry) {
78                            Entry::Insert => {
79                                map.inner.entries.insert(key, value);
80                            }
81                            Entry::Repeat => add_repeated(map, &key, value),
82                            Entry::Ignore => {}
83                        }
84                    }
85                }
86                Building::None => {}
87            }
88        }
89    }
90
91    /// Prepares for the next value in the container.
92    ///
93    /// A key that was given before collects the values in a multimap,
94    /// otherwise the [`DuplicateKeys`] policy decides.
95    fn begin_value(&mut self, state: &State) -> Result<(), Error> {
96        match self.building {
97            Building::Map(ref map) => {
98                let key = self
99                    .slot
100                    .take()
101                    .ok_or_else(|| Error::new(ErrorKind::InvalidState, "missing map key"))?;
102                if map.contains_key(&key) {
103                    self.entry = if map.is_multimap() {
104                        Entry::Repeat
105                    } else {
106                        match DuplicateKeys::of(state) {
107                            DuplicateKeys::Last => Entry::Insert,
108                            DuplicateKeys::First => Entry::Ignore,
109                            _ => return Err(duplicate_key(&key)),
110                        }
111                    };
112                }
113                self.key = Some(key);
114            }
115            _ => self.flush(),
116        }
117        Ok(())
118    }
119}
120
121/// Merges the entries of a map into another map.
122///
123/// The values of keys that exist are replaced (not merged), the entries keep
124/// their position.  New entries are added at the end.  Keys in `map` are
125/// unique, so the entries it adds cannot collide with each other.
126fn merge_map(target: &mut Map, mut map: Map) {
127    if target.is_empty() {
128        *target = map;
129        return;
130    }
131    let entries = &mut target.inner.entries;
132    entries.reserve(map.len());
133    for (key, value) in std::mem::take(&mut map.inner.entries) {
134        entries.insert(key, value);
135    }
136}
137
138/// Adds the value of a key of a multimap that was given before.
139///
140/// The values of the key become a sequence that is marked as repeated.
141#[cold]
142fn add_repeated(map: &mut Map, key: &Value, value: Value) {
143    let Some(existing) = map.inner.entries.get_mut(key) else {
144        return;
145    };
146    match existing.kind {
147        Kind::Seq(ref mut seq) if seq.is_repeated() => seq.items.push(value),
148        _ => {
149            let first = std::mem::replace(existing, Value::from(()));
150            let mut seq = Seq::from(vec![first, value]);
151            seq.set_repeated(true);
152            *existing = Value::from(seq);
153        }
154    }
155}
156
157#[cold]
158fn duplicate_key(key: &Value) -> Error {
159    let mut err = Error::new(
160        ErrorKind::DuplicateKey,
161        format!("duplicate map key {:?}", key),
162    );
163    // point at the key if its location is known
164    if let Some(span) = key.span() {
165        err.set_offset(span.range().start);
166    }
167    err
168}
169
170impl<'a, 'de> Sink<'de> for ValueSink<'a> {
171    fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
172        match self.out {
173            Out::Value(ref mut out) => {
174                **out = Some(atom_value(atom, state)?);
175                Ok(())
176            }
177            Out::UpdateValue(ref mut out) => {
178                **out = atom_value(atom, state)?;
179                Ok(())
180            }
181            _ => default_atom(self, atom, state),
182        }
183    }
184
185    fn map(&mut self, state: &mut State) -> Result<(), Error> {
186        if let Out::Seq(_) = self.out {
187            return Err(Error::new(
188                ErrorKind::InvalidType,
189                "unexpected map, expected sequence",
190            ));
191        }
192        let shape = state.container_shape();
193        self.meta = capture_meta(state);
194        let mut map = Map::with_capacity(shape.cautious_capacity::<(Value, Value)>());
195        map.set_order(shape.order());
196        map.set_multimap(shape.is_multimap());
197        map.set_ambiguous_empty(shape.is_ambiguous_empty());
198        self.building = Building::Map(map);
199        Ok(())
200    }
201
202    fn seq(&mut self, state: &mut State) -> Result<(), Error> {
203        if let Out::Map(_) | Out::UpdateMap(_) = self.out {
204            return Err(Error::new(
205                ErrorKind::InvalidType,
206                "unexpected sequence, expected map",
207            ));
208        }
209        let shape = state.container_shape();
210        self.meta = capture_meta(state);
211        let mut seq = Seq::with_capacity(shape.cautious_capacity::<Value>());
212        seq.set_order(shape.order());
213        seq.set_ambiguous_empty(shape.is_ambiguous_empty());
214        self.building = Building::Seq(seq);
215        Ok(())
216    }
217
218    fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
219        self.flush();
220        Ok(Value::deserialize_into(&mut self.slot, state))
221    }
222
223    fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
224        self.begin_value(state)?;
225        Ok(Value::deserialize_into(&mut self.slot, state))
226    }
227
228    fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
229        self.flush();
230        self.slot = Some(atom_value(atom, state)?);
231        Ok(())
232    }
233
234    fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
235        self.begin_value(state)?;
236        self.slot = Some(atom_value(atom, state)?);
237        Ok(())
238    }
239
240    fn __private_borrowed_key_atom(
241        &mut self,
242        atom: Atom<'de>,
243        state: &mut State,
244    ) -> Result<(), Error> {
245        self.__private_key_atom(atom, state)
246    }
247
248    fn __private_borrowed_value_atom(
249        &mut self,
250        atom: Atom<'de>,
251        state: &mut State,
252    ) -> Result<(), Error> {
253        self.__private_value_atom(atom, state)
254    }
255
256    /// Takes all keys when the value is flattened into a struct.
257    fn value_for_key(
258        &mut self,
259        key: &str,
260        state: &mut State,
261    ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
262        match self.building {
263            Building::Map(_) => self.flush(),
264            Building::None if !matches!(self.out, Out::Seq(_)) => {
265                let mut map = Map::new();
266                map.set_multimap(state.is_multimap());
267                self.building = Building::Map(map);
268            }
269            _ => return Ok(None),
270        }
271        self.slot = Some(Value::from(key));
272        self.begin_value(state)?;
273        Ok(Some(Value::deserialize_into(&mut self.slot, state)))
274    }
275
276    fn finish(&mut self, state: &mut State) -> Result<(), Error> {
277        self.flush();
278        let kind = match std::mem::replace(&mut self.building, Building::None) {
279            // a value that is flattened into a struct is an empty map if no
280            // key was left for it
281            Building::None => match self.out {
282                Out::Value(ref mut out @ None) => {
283                    **out = Some(Value::from(Map::new()));
284                    return Ok(());
285                }
286                Out::Map(ref mut out @ None) => {
287                    **out = Some(Map::new());
288                    return Ok(());
289                }
290                // updates keep the value
291                _ => return Ok(()),
292            },
293            Building::Seq(seq) => Kind::Seq(seq),
294            Building::Map(map) => Kind::Map(map),
295        };
296        if let Some(ref mut meta) = self.meta
297            && let Some(span) = meta.span_mut()
298            && let Some(range) = state.input_range()
299        {
300            span.set_end(range.start, range.end);
301        }
302        match (&mut self.out, kind) {
303            (Out::Value(out), kind) => {
304                **out = Some(Value {
305                    kind,
306                    meta: self.meta.take(),
307                })
308            }
309            (Out::Seq(out), Kind::Seq(seq)) => **out = Some(seq),
310            (Out::Map(out), Kind::Map(map)) => **out = Some(map),
311            // maps are merged into maps (the value keeps its meta data),
312            // everything else is replaced
313            (Out::UpdateValue(out), kind) => match (&mut out.kind, kind) {
314                (Kind::Map(target), Kind::Map(map)) => merge_map(target, map),
315                // an empty sequence that can be an empty map changes nothing
316                (Kind::Map(_), Kind::Seq(seq)) if seq.is_ambiguous_empty() => {}
317                (_, kind) => {
318                    **out = Value {
319                        kind,
320                        meta: self.meta.take(),
321                    }
322                }
323            },
324            (Out::UpdateMap(out), Kind::Map(map)) => merge_map(out, map),
325            _ => unreachable!(),
326        }
327        Ok(())
328    }
329
330    fn expecting(&self) -> Cow<'_, str> {
331        Cow::Borrowed(match self.out {
332            Out::Value(_) | Out::UpdateValue(_) => "any value",
333            Out::Seq(_) => "sequence",
334            Out::Map(_) | Out::UpdateMap(_) => "map",
335        })
336    }
337}
338
339/// Captures the meta data of the current event.
340fn capture_meta(state: &State) -> Option<Box<Meta>> {
341    let span = match (state.input_range(), state.get::<Source>()) {
342        (Some(range), Some(source)) => Some(Span::new(range, source.0.clone())),
343        _ => None,
344    };
345    let event_data = state.capture_event_data();
346    if span.is_none() && event_data.is_empty() {
347        return None;
348    }
349    Some(Box::new(Meta::from_parts(event_data, span)))
350}
351
352/// Converts an atom into a value.
353fn atom_value(atom: Atom, state: &State) -> Result<Value, Error> {
354    let kind = match atom {
355        Atom::Null => Kind::Null,
356        Atom::Bool(value) => Kind::Bool(value),
357        Atom::Str(value) => Kind::Str(value.into_owned()),
358        Atom::Lexical(value) => Kind::Lexical(value.into_owned()),
359        Atom::Bytes(value) => Kind::Bytes(owned_bytes(value)),
360        Atom::Char(value) => Kind::Char(value),
361        Atom::U64(value) => Kind::U64(value),
362        Atom::I64(value) => Kind::from_i64(value),
363        Atom::F32(value) => Kind::F32(value),
364        Atom::F64(value) => Kind::F64(value),
365        Atom::Ext(value) => Kind::from_ext(value),
366        Atom::Implicit(value) => Kind::Implicit(value.to_static()),
367        other => return Err(other.unexpected_error("any value")),
368    };
369    Ok(Value {
370        kind,
371        meta: capture_meta(state),
372    })
373}
374
375impl<'de> Deserialize<'de> for Value {
376    fn deserialize_into<'out>(
377        out: &'out mut Option<Self>,
378        state: &mut State,
379    ) -> SinkHandle<'out, 'de> {
380        SinkHandle::arena(ValueSink::new(Out::Value(out)), state)
381    }
382
383    fn expecting() -> Cow<'static, str> {
384        Cow::Borrowed("any value")
385    }
386
387    #[doc(hidden)]
388    fn __private_atom_into(
389        out: &mut Option<Self>,
390        atom: Atom,
391        state: &mut State,
392    ) -> Result<(), Error> {
393        *out = Some(atom_value(atom, state)?);
394        Ok(())
395    }
396
397    #[doc(hidden)]
398    fn __private_borrowed_atom_into(
399        out: &mut Option<Self>,
400        atom: Atom<'de>,
401        state: &mut State,
402    ) -> Result<(), Error> {
403        *out = Some(atom_value(atom, state)?);
404        Ok(())
405    }
406
407    /// Updates the value: a map merges the data into it if it's a map (the
408    /// values of keys that exist are replaced), all other values are
409    /// replaced.
410    fn deserialize_update<'out>(value: &'out mut Self, state: &mut State) -> SinkHandle<'out, 'de> {
411        SinkHandle::arena(ValueSink::new(Out::UpdateValue(value)), state)
412    }
413}
414
415impl<'de> Deserialize<'de> for Seq {
416    fn deserialize_into<'out>(
417        out: &'out mut Option<Self>,
418        state: &mut State,
419    ) -> SinkHandle<'out, 'de> {
420        SinkHandle::arena(ValueSink::new(Out::Seq(out)), state)
421    }
422
423    fn expecting() -> Cow<'static, str> {
424        Cow::Borrowed("sequence")
425    }
426}
427
428impl<'de> Deserialize<'de> for Map {
429    fn deserialize_into<'out>(
430        out: &'out mut Option<Self>,
431        state: &mut State,
432    ) -> SinkHandle<'out, 'de> {
433        SinkHandle::arena(ValueSink::new(Out::Map(out)), state)
434    }
435
436    fn expecting() -> Cow<'static, str> {
437        Cow::Borrowed("map")
438    }
439
440    /// Merges the data into the map, the values of keys that exist are
441    /// replaced.
442    fn deserialize_update<'out>(value: &'out mut Self, state: &mut State) -> SinkHandle<'out, 'de> {
443        SinkHandle::arena(ValueSink::new(Out::UpdateMap(value)), state)
444    }
445}