Skip to main content

deser_path/
ser.rs

1use deser_core::ser::{Layer, Next};
2use deser_core::{Error, Event, State};
3
4use crate::{Frame, Path, PathLayer, PathSegment};
5
6/// Tracks the path during serialization.
7///
8/// The format receives the events with the path of the value they belong
9/// to (map keys with the path of the map).  After an event was passed on,
10/// the path is updated for the value that follows, so that its
11/// [`Serialize`](deser_core::Serialize) implementation can access it.
12impl Layer for PathLayer {
13    fn event(&mut self, event: Event<'_>, next: &mut Next<'_>) -> Result<(), Error> {
14        if !self.registered {
15            self.register(next.state_mut(), false);
16        }
17        match event {
18            Event::MapEnd | Event::SeqEnd => {
19                if let Some(Frame::Seq(_)) = self.frames.pop() {
20                    next.state_mut().get_mut::<Path>().pop();
21                }
22                next.emit(event)?;
23                self.complete_item(next.state_mut(), None);
24            }
25            Event::MapStart(_) | Event::SeqStart(_) => {
26                let is_map = matches!(event, Event::MapStart(_));
27                next.emit(event)?;
28                if is_map {
29                    self.frames.push(Frame::Map(false));
30                } else {
31                    self.frames.push(Frame::Seq(0));
32                    next.state_mut()
33                        .get_mut::<Path>()
34                        .push(PathSegment::Index(0));
35                }
36            }
37            Event::Atom(ref atom) => {
38                let key = match self.frames.last() {
39                    Some(Frame::Map(false)) => {
40                        Some(next.state_mut().get_mut::<Path>().key_segment(atom))
41                    }
42                    _ => None,
43                };
44                next.emit(event)?;
45                self.complete_item(next.state_mut(), key);
46            }
47        }
48        Ok(())
49    }
50}
51
52impl PathLayer {
53    /// Updates the path after an item of the current container was
54    /// serialized.
55    ///
56    /// For map keys the key segment is given.
57    fn complete_item(&mut self, state: &mut State, key: Option<PathSegment>) {
58        match self.frames.last_mut() {
59            Some(Frame::Map(in_value)) => {
60                let path = state.get_mut::<Path>();
61                if *in_value {
62                    path.pop();
63                } else {
64                    path.push(key.unwrap_or(PathSegment::Unknown));
65                }
66                *in_value = !*in_value;
67            }
68            Some(Frame::Seq(index)) => {
69                *index += 1;
70                let index = *index;
71                state.get_mut::<Path>().set_last(PathSegment::Index(index));
72            }
73            None => {}
74        }
75    }
76}