1// SPDX-License-Identifier: Apache-2.0
2
3use super::{Error, Value};
4
5use alloc::{vec, vec::Vec};
6
7use ::serde::ser::{self, SerializeMap as _, SerializeSeq as _, SerializeTupleVariant as _};
8
9impl ser::Serialize for Value {
10 #[inline]
11 fn serialize<S: ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
12 match self {
13 Value::Bytes(x) => serializer.serialize_bytes(x),
14 Value::Bool(x) => serializer.serialize_bool(*x),
15 Value::Text(x) => serializer.serialize_str(x),
16 Value::Null => serializer.serialize_unit(),
17
18 Value::Tag(t, v) => {
19 let mut acc = serializer.serialize_tuple_variant("@@TAG@@", 0, "@@TAGGED@@", 2)?;
20 acc.serialize_field(t)?;
21 acc.serialize_field(v)?;
22 acc.end()
23 }
24
25 Value::Float(x) => {
26 let y = *x as f32;
27 if (y as f64).to_bits() == x.to_bits() {
28 serializer.serialize_f32(y)
29 } else {
30 serializer.serialize_f64(*x)
31 }
32 }
33
34 Value::Integer(x) => {
35 if let Ok(x) = u8::try_from(*x) {
36 serializer.serialize_u8(x)
37 } else if let Ok(x) = i8::try_from(*x) {
38 serializer.serialize_i8(x)
39 } else if let Ok(x) = u16::try_from(*x) {
40 serializer.serialize_u16(x)
41 } else if let Ok(x) = i16::try_from(*x) {
42 serializer.serialize_i16(x)
43 } else if let Ok(x) = u32::try_from(*x) {
44 serializer.serialize_u32(x)
45 } else if let Ok(x) = i32::try_from(*x) {
46 serializer.serialize_i32(x)
47 } else if let Ok(x) = u64::try_from(*x) {
48 serializer.serialize_u64(x)
49 } else if let Ok(x) = i64::try_from(*x) {
50 serializer.serialize_i64(x)
51 } else if let Ok(x) = u128::try_from(*x) {
52 serializer.serialize_u128(x)
53 } else if let Ok(x) = i128::try_from(*x) {
54 serializer.serialize_i128(x)
55 } else {
56 unreachable!()
57 }
58 }
59
60 Value::Array(x) => {
61 let mut map = serializer.serialize_seq(Some(x.len()))?;
62
63 for v in x {
64 map.serialize_element(v)?;
65 }
66
67 map.end()
68 }
69
70 Value::Map(x) => {
71 let mut map = serializer.serialize_map(Some(x.len()))?;
72
73 for (k, v) in x {
74 map.serialize_entry(k, v)?;
75 }
76
77 map.end()
78 }
79 }
80 }
81}
82
83macro_rules! mkserialize {
84 ($($f:ident($v:ty)),+ $(,)?) => {
85 $(
86 #[inline]
87 fn $f(self, v: $v) -> Result<Self::Ok, Self::Error> {
88 Ok(v.into())
89 }
90 )+
91 };
92}
93
94struct Tagged {
95 tag: Option<u64>,
96 val: Option<Value>,
97}
98
99struct Named<T> {
100 name: &'static str,
101 data: T,
102 tag: Option<Tagged>,
103}
104
105struct Map {
106 data: Vec<(Value, Value)>,
107 temp: Option<Value>,
108}
109
110struct Serializer<T>(T);
111
112impl ser::Serializer for Serializer<()> {
113 type Ok = Value;
114 type Error = Error;
115
116 type SerializeSeq = Serializer<Vec<Value>>;
117 type SerializeTuple = Serializer<Vec<Value>>;
118 type SerializeTupleStruct = Serializer<Vec<Value>>;
119 type SerializeTupleVariant = Serializer<Named<Vec<Value>>>;
120 type SerializeMap = Serializer<Map>;
121 type SerializeStruct = Serializer<Vec<(Value, Value)>>;
122 type SerializeStructVariant = Serializer<Named<Vec<(Value, Value)>>>;
123
124 mkserialize! {
125 serialize_bool(bool),
126
127 serialize_f32(f32),
128 serialize_f64(f64),
129
130 serialize_i8(i8),
131 serialize_i16(i16),
132 serialize_i32(i32),
133 serialize_i64(i64),
134 serialize_i128(i128),
135 serialize_u8(u8),
136 serialize_u16(u16),
137 serialize_u32(u32),
138 serialize_u64(u64),
139 serialize_u128(u128),
140
141 serialize_char(char),
142 serialize_str(&str),
143 serialize_bytes(&[u8]),
144 }
145
146 #[inline]
147 fn serialize_none(self) -> Result<Value, Error> {
148 Ok(Value::Null)
149 }
150
151 #[inline]
152 fn serialize_some<U: ?Sized + ser::Serialize>(self, value: &U) -> Result<Value, Error> {
153 value.serialize(self)
154 }
155
156 #[inline]
157 fn serialize_unit(self) -> Result<Value, Error> {
158 self.serialize_none()
159 }
160
161 #[inline]
162 fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
163 self.serialize_unit()
164 }
165
166 #[inline]
167 fn serialize_unit_variant(
168 self,
169 _name: &'static str,
170 _index: u32,
171 variant: &'static str,
172 ) -> Result<Value, Error> {
173 Ok(variant.into())
174 }
175
176 #[inline]
177 fn serialize_newtype_struct<U: ?Sized + ser::Serialize>(
178 self,
179 _name: &'static str,
180 value: &U,
181 ) -> Result<Value, Error> {
182 value.serialize(self)
183 }
184
185 #[inline]
186 fn serialize_newtype_variant<U: ?Sized + ser::Serialize>(
187 self,
188 name: &'static str,
189 _index: u32,
190 variant: &'static str,
191 value: &U,
192 ) -> Result<Value, Error> {
193 Ok(match (name, variant) {
194 ("@@TAG@@", "@@UNTAGGED@@") => Value::serialized(value)?,
195 _ => vec![(variant.into(), Value::serialized(value)?)].into(),
196 })
197 }
198
199 #[inline]
200 fn serialize_seq(self, length: Option<usize>) -> Result<Self::SerializeSeq, Error> {
201 Ok(Serializer(Vec::with_capacity(length.unwrap_or(0))))
202 }
203
204 #[inline]
205 fn serialize_tuple(self, length: usize) -> Result<Self::SerializeTuple, Error> {
206 self.serialize_seq(Some(length))
207 }
208
209 #[inline]
210 fn serialize_tuple_struct(
211 self,
212 _name: &'static str,
213 length: usize,
214 ) -> Result<Self::SerializeTupleStruct, Error> {
215 self.serialize_seq(Some(length))
216 }
217
218 #[inline]
219 fn serialize_tuple_variant(
220 self,
221 name: &'static str,
222 _index: u32,
223 variant: &'static str,
224 length: usize,
225 ) -> Result<Self::SerializeTupleVariant, Error> {
226 Ok(Serializer(Named {
227 name: variant,
228 data: Vec::with_capacity(length),
229 tag: match (name, variant) {
230 ("@@TAG@@", "@@TAGGED@@") => Some(Tagged {
231 tag: None,
232 val: None,
233 }),
234
235 _ => None,
236 },
237 }))
238 }
239
240 #[inline]
241 fn serialize_map(self, length: Option<usize>) -> Result<Self::SerializeMap, Error> {
242 Ok(Serializer(Map {
243 data: Vec::with_capacity(length.unwrap_or(0)),
244 temp: None,
245 }))
246 }
247
248 #[inline]
249 fn serialize_struct(
250 self,
251 _name: &'static str,
252 length: usize,
253 ) -> Result<Self::SerializeStruct, Error> {
254 Ok(Serializer(Vec::with_capacity(length)))
255 }
256
257 #[inline]
258 fn serialize_struct_variant(
259 self,
260 _name: &'static str,
261 _index: u32,
262 variant: &'static str,
263 length: usize,
264 ) -> Result<Self::SerializeStructVariant, Error> {
265 Ok(Serializer(Named {
266 name: variant,
267 data: Vec::with_capacity(length),
268 tag: None,
269 }))
270 }
271}
272
273impl ser::SerializeSeq for Serializer<Vec<Value>> {
274 type Ok = Value;
275 type Error = Error;
276
277 #[inline]
278 fn serialize_element<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
279 self.0.push(Value::serialized(&value)?);
280 Ok(())
281 }
282
283 #[inline]
284 fn end(self) -> Result<Self::Ok, Self::Error> {
285 Ok(self.0.into())
286 }
287}
288
289impl ser::SerializeTuple for Serializer<Vec<Value>> {
290 type Ok = Value;
291 type Error = Error;
292
293 #[inline]
294 fn serialize_element<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
295 self.0.push(Value::serialized(&value)?);
296 Ok(())
297 }
298
299 #[inline]
300 fn end(self) -> Result<Self::Ok, Self::Error> {
301 Ok(self.0.into())
302 }
303}
304
305impl ser::SerializeTupleStruct for Serializer<Vec<Value>> {
306 type Ok = Value;
307 type Error = Error;
308
309 #[inline]
310 fn serialize_field<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
311 self.0.push(Value::serialized(&value)?);
312 Ok(())
313 }
314
315 #[inline]
316 fn end(self) -> Result<Self::Ok, Self::Error> {
317 Ok(self.0.into())
318 }
319}
320
321impl ser::SerializeTupleVariant for Serializer<Named<Vec<Value>>> {
322 type Ok = Value;
323 type Error = Error;
324
325 #[inline]
326 fn serialize_field<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
327 match self.0.tag.as_mut() {
328 Some(tag) => match tag.tag {
329 None => match value.serialize(crate::tag::Serializer) {
330 Ok(t) => tag.tag = Some(t),
331 Err(..) => return Err(ser::Error::custom("expected tag")),
332 },
333
334 Some(..) => tag.val = Some(Value::serialized(value)?),
335 },
336
337 None => self.0.data.push(Value::serialized(value)?),
338 }
339
340 Ok(())
341 }
342
343 #[inline]
344 fn end(self) -> Result<Self::Ok, Self::Error> {
345 Ok(match self.0.tag {
346 Some(tag) => match tag {
347 Tagged {
348 tag: Some(t),
349 val: Some(v),
350 } => Value::Tag(t, v.into()),
351 _ => return Err(ser::Error::custom("invalid tag input")),
352 },
353
354 None => vec![(self.0.name.into(), self.0.data.into())].into(),
355 })
356 }
357}
358
359impl ser::SerializeMap for Serializer<Map> {
360 type Ok = Value;
361 type Error = Error;
362
363 #[inline]
364 fn serialize_key<U: ?Sized + ser::Serialize>(&mut self, key: &U) -> Result<(), Error> {
365 self.0.temp = Some(Value::serialized(key)?);
366 Ok(())
367 }
368
369 #[inline]
370 fn serialize_value<U: ?Sized + ser::Serialize>(&mut self, value: &U) -> Result<(), Error> {
371 let key = self.0.temp.take().unwrap();
372 let val = Value::serialized(&value)?;
373
374 self.0.data.push((key, val));
375 Ok(())
376 }
377
378 #[inline]
379 fn end(self) -> Result<Self::Ok, Self::Error> {
380 Ok(self.0.data.into())
381 }
382}
383
384impl ser::SerializeStruct for Serializer<Vec<(Value, Value)>> {
385 type Ok = Value;
386 type Error = Error;
387
388 #[inline]
389 fn serialize_field<U: ?Sized + ser::Serialize>(
390 &mut self,
391 key: &'static str,
392 value: &U,
393 ) -> Result<(), Error> {
394 let k = Value::serialized(&key)?;
395 let v = Value::serialized(&value)?;
396 self.0.push((k, v));
397 Ok(())
398 }
399
400 #[inline]
401 fn end(self) -> Result<Self::Ok, Self::Error> {
402 Ok(self.0.into())
403 }
404}
405
406impl ser::SerializeStructVariant for Serializer<Named<Vec<(Value, Value)>>> {
407 type Ok = Value;
408 type Error = Error;
409
410 #[inline]
411 fn serialize_field<U: ?Sized + ser::Serialize>(
412 &mut self,
413 key: &'static str,
414 value: &U,
415 ) -> Result<(), Self::Error> {
416 let k = Value::serialized(&key)?;
417 let v = Value::serialized(&value)?;
418 self.0.data.push((k, v));
419 Ok(())
420 }
421
422 #[inline]
423 fn end(self) -> Result<Self::Ok, Self::Error> {
424 Ok(vec![(self.0.name.into(), self.0.data.into())].into())
425 }
426}
427
428impl Value {
429 /// Serializes an object into a `Value`
430 #[inline]
431 pub fn serialized<T: ?Sized + ser::Serialize>(value: &T) -> Result<Self, Error> {
432 value.serialize(Serializer(()))
433 }
434}
435