deser_path/
de.rs

1use std::borrow::Cow;
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use deser::de::{DeserializerState, Sink, SinkHandle};
6use deser::{Atom, Descriptor, Error};
7
8use crate::{Path, PathSegment};
9
10enum Container {
11    None,
12    Map(Rc<RefCell<Option<PathSegment>>>),
13    Seq(usize),
14}
15
16/// A path sink tracks the current path during deserialization.
17pub struct PathSink<'a> {
18    sink: SinkHandle<'a>,
19    container: Container,
20    set_segment: Option<PathSegment>,
21}
22
23impl<'a> PathSink<'a> {
24    /// Wraps a sink.
25    pub fn wrap(sink: &'a mut dyn Sink) -> PathSink<'a> {
26        PathSink::wrap_ref(SinkHandle::to(sink))
27    }
28
29    /// Wraps a sink ref.
30    pub fn wrap_ref(sink: SinkHandle<'a>) -> PathSink<'a> {
31        PathSink {
32            sink,
33            container: Container::None,
34            set_segment: None,
35        }
36    }
37
38    fn set_segment(&mut self, state: &DeserializerState) {
39        if let Some(segment) = self.set_segment.take() {
40            *state.get_mut::<Path>().segments.last_mut().unwrap() = segment;
41        }
42    }
43}
44
45impl<'a> Sink for PathSink<'a> {
46    fn atom(&mut self, atom: Atom, state: &DeserializerState) -> Result<(), Error> {
47        self.set_segment(state);
48        if let Container::Map(ref capture) = self.container {
49            *capture.borrow_mut() = match atom {
50                Atom::Str(ref value) => Some(PathSegment::Key(value.to_string())),
51                Atom::U64(value) => Some(PathSegment::Index(value as usize)),
52                Atom::I64(value) => Some(PathSegment::Index(value as usize)),
53                _ => None,
54            };
55        }
56        self.sink.atom(atom, state)
57    }
58
59    fn map(&mut self, state: &DeserializerState) -> Result<(), Error> {
60        self.set_segment(state);
61        state.get_mut::<Path>().segments.push(PathSegment::Unknown);
62        self.container = Container::Map(Rc::default());
63        self.sink.map(state)
64    }
65
66    fn seq(&mut self, state: &DeserializerState) -> Result<(), Error> {
67        self.set_segment(state);
68        state.get_mut::<Path>().segments.push(PathSegment::Unknown);
69        self.container = Container::Seq(0);
70        self.sink.seq(state)
71    }
72
73    fn next_key(&mut self, state: &DeserializerState) -> Result<SinkHandle, Error> {
74        self.sink.next_key(state).map(|sink| {
75            SinkHandle::boxed(PathSink {
76                sink,
77                container: match self.container {
78                    Container::Map(ref capture) => Container::Map(capture.clone()),
79                    _ => unreachable!(),
80                },
81                set_segment: None,
82            })
83        })
84    }
85
86    fn next_value(&mut self, state: &DeserializerState) -> Result<SinkHandle, Error> {
87        let set_segment = match self.container {
88            Container::None => None,
89            Container::Map(ref captured_key) => captured_key.borrow_mut().take(),
90            Container::Seq(ref mut index) => {
91                let old_index = *index;
92                *index += 1;
93                Some(PathSegment::Index(old_index))
94            }
95        };
96        self.sink.next_value(state).map(|sink| {
97            SinkHandle::boxed(PathSink {
98                sink,
99                container: Container::None,
100                set_segment,
101            })
102        })
103    }
104
105    fn finish(&mut self, state: &DeserializerState) -> Result<(), Error> {
106        self.sink.finish(state)
107    }
108
109    fn descriptor(&self) -> &dyn Descriptor {
110        self.sink.descriptor()
111    }
112
113    fn expecting(&self) -> Cow<'_, str> {
114        self.sink.expecting()
115    }
116}