1use alloc::vec::Vec;
3use core::fmt;
4
5use alloc::borrow::Cow;
6
7use deser_core::State;
8use deser_core::de::{Deserialize, OwnedSink, Sink, SinkHandle};
9use deser_core::ser::{Describe, Emit, Serialize};
10use deser_core::{Atom, ContainerShape, Error};
11
12#[derive(Debug, Default)]
18pub(crate) struct Tags(pub(crate) Vec<u64>);
19
20impl Clone for Tags {
23 fn clone(&self) -> Tags {
24 Tags(self.0.clone())
25 }
26
27 fn clone_from(&mut self, source: &Tags) {
28 self.0.clone_from(&source.0);
29 }
30}
31
32pub fn take_tag(state: &mut State) -> Option<u64> {
48 if state.event::<Tags>().is_some_and(|tags| !tags.0.is_empty()) {
49 let tags = &mut state.event_mut::<Tags>().0;
50 let tag = tags.remove(0);
51 if tags.is_empty() {
55 state.take_event::<Tags>();
56 }
57 Some(tag)
58 } else {
59 None
60 }
61}
62
63pub fn push_tag(state: &mut State, tag: u64) {
70 state.event_mut::<Tags>().0.push(tag);
71}
72
73#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
95pub struct Tagged<T> {
96 pub tag: Option<u64>,
98 pub value: T,
100}
101
102impl<T> Tagged<T> {
103 pub fn new(tag: u64, value: T) -> Tagged<T> {
105 Tagged {
106 tag: Some(tag),
107 value,
108 }
109 }
110
111 pub fn untagged(value: T) -> Tagged<T> {
113 Tagged { tag: None, value }
114 }
115
116 pub fn into_inner(self) -> T {
118 self.value
119 }
120}
121
122impl<T: fmt::Debug> fmt::Debug for Tagged<T> {
123 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
124 match self.tag {
125 Some(tag) => {
126 write!(f, "{}(", tag)?;
127 fmt::Debug::fmt(&self.value, f)?;
128 write!(f, ")")
129 }
130 None => fmt::Debug::fmt(&self.value, f),
131 }
132 }
133}
134
135impl<T: Serialize> Serialize for Tagged<T> {
136 fn serialize<'a>(this: &'a Self, state: &mut State) -> Result<Emit<'a>, Error> {
137 let emit = T::serialize(&this.value, state)?;
140 if let Some(tag) = this.tag {
141 state.event_mut::<Tags>().0.insert(0, tag);
142 }
143 Ok(emit)
144 }
145
146 fn finish(this: &Self, state: &mut State) -> Result<(), Error> {
147 T::finish(&this.value, state)
148 }
149
150 fn is_optional(this: &Self) -> bool {
151 T::is_optional(&this.value)
152 }
153
154 fn container_shape(this: &Self) -> ContainerShape {
155 T::container_shape(&this.value)
156 }
157
158 fn describe(this: &Self, d: &mut dyn Describe) {
159 T::describe(&this.value, d)
160 }
161}
162
163impl<'de, T: Deserialize<'de>> Deserialize<'de> for Tagged<T> {
164 fn deserialize_into<'out>(
165 out: &'out mut Option<Self>,
166 state: &mut State,
167 ) -> SinkHandle<'out, 'de> {
168 SinkHandle::arena(
169 TaggedSink {
170 out,
171 slot: None,
172 compound: None,
173 tag: None,
174 },
175 state,
176 )
177 }
178
179 fn expecting() -> Cow<'static, str> {
180 T::expecting()
181 }
182
183 fn describe_type(d: &mut dyn Describe) {
184 T::describe_type(d)
185 }
186}
187
188struct TaggedSink<'a, 'de, T> {
189 out: &'a mut Option<Tagged<T>>,
190 slot: Option<T>,
193 compound: Option<OwnedSink<'de, T>>,
194 tag: Option<u64>,
195}
196
197impl<'a, 'de, T: Deserialize<'de>> TaggedSink<'a, 'de, T> {
198 fn compound(&mut self, state: &mut State) -> &mut dyn Sink<'de> {
199 self.compound
200 .get_or_insert_with(|| OwnedSink::deserialize(state))
201 .get_mut()
202 }
203}
204
205impl<'a, 'de, T: Deserialize<'de>> Sink<'de> for TaggedSink<'a, 'de, T> {
206 fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
207 self.tag = take_tag(state);
208 let mut sink = T::deserialize_into(&mut self.slot, state);
209 sink.atom(atom, state)?;
210 sink.finish(state)
211 }
212
213 fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
214 self.tag = take_tag(state);
215 let mut sink = T::deserialize_into(&mut self.slot, state);
216 sink.borrowed_atom(atom, state)?;
217 sink.finish(state)
218 }
219
220 fn map(&mut self, state: &mut State) -> Result<(), Error> {
221 self.tag = take_tag(state);
222 self.compound(state).map(state)
223 }
224
225 fn seq(&mut self, state: &mut State) -> Result<(), Error> {
226 self.tag = take_tag(state);
227 self.compound(state).seq(state)
228 }
229
230 fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
231 self.compound(state).next_key(state)
232 }
233
234 fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
235 self.compound(state).next_value(state)
236 }
237
238 fn value_for_key(
239 &mut self,
240 key: &str,
241 state: &mut State,
242 ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
243 self.compound(state).value_for_key(key, state)
244 }
245
246 fn recover(&mut self, err: Error, state: &mut State) -> Result<(), Error> {
247 match self.compound {
248 Some(ref mut compound) => compound.get_mut().recover(err, state),
249 None => Err(err),
250 }
251 }
252
253 fn finish(&mut self, state: &mut State) -> Result<(), Error> {
254 let value = match self.compound {
255 Some(ref mut compound) => {
256 compound.get_mut().finish(state)?;
257 compound.take()
258 }
259 None => self.slot.take(),
260 };
261 let tag = self.tag;
262 *self.out = value.map(|value| Tagged { tag, value });
263 Ok(())
264 }
265
266 fn expecting(&self) -> Cow<'_, str> {
267 if let Some(ref compound) = self.compound {
268 return compound.get().expecting();
269 }
270 T::expecting()
271 }
272}