Skip to main content

deser_path/
de.rs

1use deser_core::de::{Layer, LayerEvent, Next};
2use deser_core::{Error, Event};
3
4use crate::{Frame, Path, PathLayer, PathSegment};
5
6/// Tracks the path during deserialization.
7///
8/// The path of a value is set before the value is passed on, so that the
9/// sinks can access it.  Containers push a segment for their items after
10/// they started and pop it before they end, so the path of a container is
11/// its own path while it's finished.
12impl Layer for PathLayer {
13    fn event<'de>(
14        &mut self,
15        event: LayerEvent<'_, 'de>,
16        next: &mut Next<'_, 'de>,
17    ) -> Result<(), Error> {
18        if !self.registered {
19            self.register(next.state_mut(), true);
20        }
21        let is_map = match *event.event() {
22            Event::MapEnd | Event::SeqEnd => {
23                self.frames.pop();
24                next.state_mut().get_mut::<Path>().pop();
25                return next.emit(event);
26            }
27            Event::MapStart(_) => Some(true),
28            Event::SeqStart(_) => Some(false),
29            Event::Atom(_) => None,
30        };
31
32        let is_map_key = next.state().is_map_key();
33        match self.frames.last_mut() {
34            Some(Frame::Seq(index)) => {
35                let segment = PathSegment::Index(*index);
36                *index += 1;
37                next.state_mut().get_mut::<Path>().set_last(segment);
38            }
39            Some(Frame::Map(_)) if is_map_key => {
40                let path = next.state_mut().get_mut::<Path>();
41                match *event.event() {
42                    Event::Atom(ref atom) => path.set_last_key(atom),
43                    _ => path.set_last(PathSegment::Unknown),
44                }
45            }
46            _ => {}
47        }
48
49        next.emit(event)?;
50
51        if let Some(is_map) = is_map {
52            self.frames.push(if is_map {
53                Frame::Map(false)
54            } else {
55                Frame::Seq(0)
56            });
57            next.state_mut()
58                .get_mut::<Path>()
59                .push(PathSegment::Unknown);
60        }
61        Ok(())
62    }
63}