1 | // SPDX-License-Identifier: Apache-2.0 |
2 | |
3 | use super::{Error, Value}; |
4 | |
5 | use alloc::{vec, vec::Vec}; |
6 | |
7 | use ::serde::ser::{self, SerializeMap as _, SerializeSeq as _, SerializeTupleVariant as _}; |
8 | |
9 | impl 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 | |
83 | macro_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 | |
94 | struct Tagged { |
95 | tag: Option<u64>, |
96 | val: Option<Value>, |
97 | } |
98 | |
99 | struct Named<T> { |
100 | name: &'static str, |
101 | data: T, |
102 | tag: Option<Tagged>, |
103 | } |
104 | |
105 | struct Map { |
106 | data: Vec<(Value, Value)>, |
107 | temp: Option<Value>, |
108 | } |
109 | |
110 | struct Serializer<T>(T); |
111 | |
112 | impl 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 | |
273 | impl 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 | |
289 | impl 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 | |
305 | impl 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 | |
321 | impl 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 | |
359 | impl 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 | |
384 | impl 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 | |
406 | impl 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 | |
428 | impl 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 | |