1use std::borrow::Cow;
2use std::cell::RefCell;
3use std::rc::Rc;
4
5use deser::ser::{
6 Chunk, MapEmitter, SeqEmitter, Serialize, SerializeHandle, SerializerState, StructEmitter,
7};
8use deser::{Atom, Error};
9
10use crate::{Path, PathSegment};
11
12pub struct PathSerializable<'a> {
14 serializable: SerializeHandle<'a>,
15}
16
17impl<'a> PathSerializable<'a> {
18 pub fn wrap(serializable: &'a dyn Serialize) -> PathSerializable<'a> {
20 PathSerializable::wrap_ref(SerializeHandle::Borrowed(serializable))
21 }
22
23 pub fn wrap_ref(serializable: SerializeHandle<'a>) -> PathSerializable<'a> {
25 PathSerializable { serializable }
26 }
27}
28
29impl<'a> Serialize for PathSerializable<'a> {
30 fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
31 match self.serializable.serialize(state)? {
32 Chunk::Struct(emitter) => Ok(Chunk::Struct(Box::new(PathStructEmitter { emitter }))),
33 Chunk::Map(emitter) => Ok(Chunk::Map(Box::new(PathMapEmitter {
34 emitter,
35 path_segment: Rc::default(),
36 }))),
37 Chunk::Seq(emitter) => Ok(Chunk::Seq(Box::new(PathSeqEmitter { emitter, index: 0 }))),
38 other => Ok(other),
39 }
40 }
41
42 fn finish(&self, state: &SerializerState) -> Result<(), Error> {
43 self.serializable.finish(state)
44 }
45}
46
47struct PathStructEmitter<'a> {
48 emitter: Box<dyn StructEmitter + 'a>,
49}
50
51impl<'a> StructEmitter for PathStructEmitter<'a> {
52 fn next(
53 &mut self,
54 state: &SerializerState,
55 ) -> Result<Option<(Cow<'_, str>, SerializeHandle)>, Error> {
56 let (key, value) = match self.emitter.next(state)? {
57 Some(result) => result,
58 None => return Ok(None),
59 };
60 let new_segment = PathSegment::Key(key.to_string());
61 let value_serializable = SegmentPushingSerializable {
62 serializable: value,
63 segment: RefCell::new(Some(new_segment)),
64 };
65 Ok(Some((key, SerializeHandle::boxed(value_serializable))))
66 }
67}
68
69struct PathMapEmitter<'a> {
70 emitter: Box<dyn MapEmitter + 'a>,
71 path_segment: Rc<RefCell<Option<PathSegment>>>,
72}
73
74impl<'a> MapEmitter for PathMapEmitter<'a> {
75 fn next_key(&mut self, state: &SerializerState) -> Result<Option<SerializeHandle>, Error> {
76 let key_serializable = SegmentCollectingSerializable {
77 serializable: match self.emitter.next_key(state)? {
78 Some(result) => result,
79 None => return Ok(None),
80 },
81 segment: self.path_segment.clone(),
82 };
83 Ok(Some(SerializeHandle::boxed(key_serializable)))
84 }
85
86 fn next_value(&mut self, state: &SerializerState) -> Result<SerializeHandle, Error> {
87 let new_segment = self
88 .path_segment
89 .borrow_mut()
90 .take()
91 .unwrap_or(PathSegment::Unknown);
92 let value_serializable = SegmentPushingSerializable {
93 serializable: self.emitter.next_value(state)?,
94 segment: RefCell::new(Some(new_segment)),
95 };
96 Ok(SerializeHandle::boxed(value_serializable))
97 }
98}
99
100struct PathSeqEmitter<'a> {
101 emitter: Box<dyn SeqEmitter + 'a>,
102 index: usize,
103}
104
105impl<'a> SeqEmitter for PathSeqEmitter<'a> {
106 fn next(&mut self, state: &SerializerState) -> Result<Option<SerializeHandle>, Error> {
107 let index = self.index;
108 self.index += 1;
109 let value = match self.emitter.next(state)? {
110 Some(result) => result,
111 None => return Ok(None),
112 };
113 let new_segment = PathSegment::Index(index);
114 let item_serializable = SegmentPushingSerializable {
115 serializable: value,
116 segment: RefCell::new(Some(new_segment)),
117 };
118 Ok(Some(SerializeHandle::boxed(item_serializable)))
119 }
120}
121
122struct SegmentPushingSerializable<'a> {
123 serializable: SerializeHandle<'a>,
124 segment: RefCell<Option<PathSegment>>,
125}
126
127impl<'a> Serialize for SegmentPushingSerializable<'a> {
128 fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
129 {
130 let mut path = state.get_mut::<Path>();
131 path.segments.push(self.segment.take().unwrap());
132 }
133 match self.serializable.serialize(state)? {
134 Chunk::Struct(emitter) => Ok(Chunk::Struct(Box::new(PathStructEmitter { emitter }))),
135 Chunk::Map(emitter) => Ok(Chunk::Map(Box::new(PathMapEmitter {
136 emitter,
137 path_segment: Rc::default(),
138 }))),
139 Chunk::Seq(emitter) => Ok(Chunk::Seq(Box::new(PathSeqEmitter { emitter, index: 0 }))),
140 other => Ok(other),
141 }
142 }
143
144 fn finish(&self, state: &SerializerState) -> Result<(), Error> {
145 self.serializable.finish(state)?;
146 let mut path = state.get_mut::<Path>();
147 path.segments.pop();
148 Ok(())
149 }
150}
151
152struct SegmentCollectingSerializable<'a> {
153 serializable: SerializeHandle<'a>,
154 segment: Rc<RefCell<Option<PathSegment>>>,
155}
156
157impl<'a> Serialize for SegmentCollectingSerializable<'a> {
158 fn serialize(&self, state: &SerializerState) -> Result<Chunk, Error> {
159 match self.serializable.serialize(state)? {
160 Chunk::Atom(Atom::Str(key)) => {
161 *self.segment.borrow_mut() = Some(PathSegment::Key(key.to_string()));
162 Ok(Chunk::Atom(Atom::Str(key)))
163 }
164 Chunk::Atom(Atom::U64(val)) => {
165 *self.segment.borrow_mut() = Some(PathSegment::Index(val as usize));
166 Ok(Chunk::Atom(Atom::U64(val)))
167 }
168 other => Ok(other),
169 }
170 }
171
172 fn finish(&self, state: &SerializerState) -> Result<(), Error> {
173 self.serializable.finish(state)
174 }
175}