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