1use serde::Serialize;
2use serde::de::DeserializeOwned;
3use serde::ser::{self, SerializeTuple as _};
4
5use super::{Mapping, Number, TAGGED_VALUE_TOKEN, Tag, TaggedValue, Value};
6use crate::{Error, Result};
7
8#[derive(Clone, Copy, Debug, Default)]
10pub struct Serializer;
11
12pub fn to_value<T>(value: T) -> Result<Value>
19where
20 T: Serialize,
21{
22 value.serialize(Serializer)
23}
24
25pub fn from_value<T>(value: Value) -> Result<T>
31where
32 T: DeserializeOwned,
33{
34 T::deserialize(value)
35}
36
37#[doc(hidden)]
39pub struct SerializeSequence {
40 values: Vec<Value>,
41 tag: Option<Tag>,
42}
43
44impl SerializeSequence {
45 fn new(len: Option<usize>, tag: Option<Tag>) -> Self {
46 Self {
47 values: Vec::with_capacity(len.unwrap_or(0)),
48 tag,
49 }
50 }
51
52 fn push<T>(&mut self, value: &T) -> Result<()>
53 where
54 T: ?Sized + Serialize,
55 {
56 self.values.push(value.serialize(Serializer)?);
57 Ok(())
58 }
59
60 fn finish(self) -> Value {
61 tagged(self.tag, Value::Sequence(self.values))
62 }
63}
64
65impl ser::SerializeSeq for SerializeSequence {
66 type Ok = Value;
67 type Error = Error;
68
69 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
70 where
71 T: ?Sized + Serialize,
72 {
73 self.push(value)
74 }
75
76 fn end(self) -> Result<Value> {
77 Ok(self.finish())
78 }
79}
80
81impl ser::SerializeTuple for SerializeSequence {
82 type Ok = Value;
83 type Error = Error;
84
85 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
86 where
87 T: ?Sized + Serialize,
88 {
89 self.push(value)
90 }
91
92 fn end(self) -> Result<Value> {
93 Ok(self.finish())
94 }
95}
96
97impl ser::SerializeTupleStruct for SerializeSequence {
98 type Ok = Value;
99 type Error = Error;
100
101 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
102 where
103 T: ?Sized + Serialize,
104 {
105 self.push(value)
106 }
107
108 fn end(self) -> Result<Value> {
109 Ok(self.finish())
110 }
111}
112
113impl ser::SerializeTupleVariant for SerializeSequence {
114 type Ok = Value;
115 type Error = Error;
116
117 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
118 where
119 T: ?Sized + Serialize,
120 {
121 self.push(value)
122 }
123
124 fn end(self) -> Result<Value> {
125 Ok(self.finish())
126 }
127}
128
129#[doc(hidden)]
131pub struct SerializeMapping {
132 entries: Mapping,
133 pending: Option<Value>,
134 tag: Option<Tag>,
135}
136
137impl SerializeMapping {
138 fn new(len: Option<usize>, tag: Option<Tag>) -> Self {
139 Self {
140 entries: Mapping::with_capacity(len.unwrap_or(0)),
141 pending: None,
142 tag,
143 }
144 }
145
146 fn insert(&mut self, key: Value, value: Value) {
147 self.entries.insert(key, value);
148 }
149
150 fn finish(self) -> Result<Value> {
151 if self.pending.is_some() {
152 return Err(Error::message("map ended before serializing a value"));
153 }
154 Ok(tagged(self.tag, Value::Mapping(self.entries)))
155 }
156}
157
158impl ser::SerializeMap for SerializeMapping {
159 type Ok = Value;
160 type Error = Error;
161
162 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
163 where
164 T: ?Sized + Serialize,
165 {
166 if self.pending.is_some() {
167 return Err(Error::message("map key serialized before its value"));
168 }
169 self.pending = Some(key.serialize(Serializer)?);
170 Ok(())
171 }
172
173 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
174 where
175 T: ?Sized + Serialize,
176 {
177 let key = self
178 .pending
179 .take()
180 .ok_or_else(|| Error::message("map value serialized before its key"))?;
181 self.insert(key, value.serialize(Serializer)?);
182 Ok(())
183 }
184
185 fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
186 where
187 K: ?Sized + Serialize,
188 V: ?Sized + Serialize,
189 {
190 self.insert(key.serialize(Serializer)?, value.serialize(Serializer)?);
191 Ok(())
192 }
193
194 fn end(self) -> Result<Value> {
195 self.finish()
196 }
197}
198
199impl ser::SerializeStruct for SerializeMapping {
200 type Ok = Value;
201 type Error = Error;
202
203 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
204 where
205 T: ?Sized + Serialize,
206 {
207 self.insert(Value::String(key.to_owned()), value.serialize(Serializer)?);
208 Ok(())
209 }
210
211 fn end(self) -> Result<Value> {
212 self.finish()
213 }
214}
215
216impl ser::SerializeStructVariant for SerializeMapping {
217 type Ok = Value;
218 type Error = Error;
219
220 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
221 where
222 T: ?Sized + Serialize,
223 {
224 ser::SerializeStruct::serialize_field(self, key, value)
225 }
226
227 fn end(self) -> Result<Value> {
228 self.finish()
229 }
230}
231
232impl ser::Serializer for Serializer {
233 type Ok = Value;
234 type Error = Error;
235 type SerializeSeq = SerializeSequence;
236 type SerializeTuple = SerializeSequence;
237 type SerializeTupleStruct = SerializeSequence;
238 type SerializeTupleVariant = SerializeSequence;
239 type SerializeMap = SerializeMapping;
240 type SerializeStruct = SerializeMapping;
241 type SerializeStructVariant = SerializeMapping;
242
243 fn serialize_bool(self, value: bool) -> Result<Value> {
244 Ok(Value::Bool(value))
245 }
246
247 fn serialize_i8(self, value: i8) -> Result<Value> {
248 self.serialize_i128(value.into())
249 }
250
251 fn serialize_i16(self, value: i16) -> Result<Value> {
252 self.serialize_i128(value.into())
253 }
254
255 fn serialize_i32(self, value: i32) -> Result<Value> {
256 self.serialize_i128(value.into())
257 }
258
259 fn serialize_i64(self, value: i64) -> Result<Value> {
260 self.serialize_i128(value.into())
261 }
262
263 fn serialize_i128(self, value: i128) -> Result<Value> {
264 Ok(Value::Number(Number::from(value)))
265 }
266
267 fn serialize_u8(self, value: u8) -> Result<Value> {
268 self.serialize_u128(value.into())
269 }
270
271 fn serialize_u16(self, value: u16) -> Result<Value> {
272 self.serialize_u128(value.into())
273 }
274
275 fn serialize_u32(self, value: u32) -> Result<Value> {
276 self.serialize_u128(value.into())
277 }
278
279 fn serialize_u64(self, value: u64) -> Result<Value> {
280 self.serialize_u128(value.into())
281 }
282
283 fn serialize_u128(self, value: u128) -> Result<Value> {
284 Ok(Value::Number(Number::from(value)))
285 }
286
287 fn serialize_f32(self, value: f32) -> Result<Value> {
288 Ok(Value::Number(Number::from(value)))
289 }
290
291 fn serialize_f64(self, value: f64) -> Result<Value> {
292 Ok(Value::Number(Number::from(value)))
293 }
294
295 fn serialize_char(self, value: char) -> Result<Value> {
296 Ok(Value::String(value.to_string()))
297 }
298
299 fn serialize_str(self, value: &str) -> Result<Value> {
300 Ok(Value::String(value.to_owned()))
301 }
302
303 fn serialize_bytes(self, _value: &[u8]) -> Result<Value> {
304 Err(Error::message(
305 "serialization and deserialization of bytes in YAML is not implemented",
306 ))
307 }
308
309 fn serialize_none(self) -> Result<Value> {
310 Ok(Value::Null)
311 }
312
313 fn serialize_some<T>(self, value: &T) -> Result<Value>
314 where
315 T: ?Sized + Serialize,
316 {
317 value.serialize(self)
318 }
319
320 fn serialize_unit(self) -> Result<Value> {
321 Ok(Value::Null)
322 }
323
324 fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
325 Ok(Value::Null)
326 }
327
328 fn serialize_unit_variant(
329 self,
330 _name: &'static str,
331 _index: u32,
332 variant: &'static str,
333 ) -> Result<Value> {
334 Ok(Value::String(variant.to_owned()))
335 }
336
337 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<Value>
338 where
339 T: ?Sized + Serialize,
340 {
341 let value = value.serialize(self)?;
342 if name != TAGGED_VALUE_TOKEN {
343 return Ok(value);
344 }
345 let Value::Sequence(mut parts) = value else {
346 return Err(Error::message("invalid tagged value payload"));
347 };
348 if parts.len() != 2 {
349 return Err(Error::message("invalid tagged value payload"));
350 }
351 let inner = parts.pop().expect("tagged payload contains a value");
352 let tag = parts.pop().expect("tagged payload contains a tag");
353 let Value::String(tag) = tag else {
354 return Err(Error::message("invalid tagged value tag"));
355 };
356 Ok(Value::Tagged(Box::new(TaggedValue {
357 tag: Tag::new(tag),
358 value: inner,
359 })))
360 }
361
362 fn serialize_newtype_variant<T>(
363 self,
364 _name: &'static str,
365 _index: u32,
366 variant: &'static str,
367 value: &T,
368 ) -> Result<Value>
369 where
370 T: ?Sized + Serialize,
371 {
372 let value = value.serialize(self)?;
373 if matches!(value, Value::Tagged(_)) {
374 return Err(Error::message(
375 "serializing nested enums in YAML is not supported",
376 ));
377 }
378 Ok(tagged(Some(Tag::new(variant)), value))
379 }
380
381 fn serialize_seq(self, len: Option<usize>) -> Result<SerializeSequence> {
382 Ok(SerializeSequence::new(len, None))
383 }
384
385 fn serialize_tuple(self, len: usize) -> Result<SerializeSequence> {
386 Ok(SerializeSequence::new(Some(len), None))
387 }
388
389 fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeSequence> {
390 Ok(SerializeSequence::new(Some(len), None))
391 }
392
393 fn serialize_tuple_variant(
394 self,
395 _name: &'static str,
396 _index: u32,
397 variant: &'static str,
398 len: usize,
399 ) -> Result<SerializeSequence> {
400 Ok(SerializeSequence::new(Some(len), Some(Tag::new(variant))))
401 }
402
403 fn serialize_map(self, len: Option<usize>) -> Result<SerializeMapping> {
404 Ok(SerializeMapping::new(len, None))
405 }
406
407 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<SerializeMapping> {
408 Ok(SerializeMapping::new(Some(len), None))
409 }
410
411 fn serialize_struct_variant(
412 self,
413 _name: &'static str,
414 _index: u32,
415 variant: &'static str,
416 len: usize,
417 ) -> Result<SerializeMapping> {
418 Ok(SerializeMapping::new(Some(len), Some(Tag::new(variant))))
419 }
420
421 fn collect_str<T>(self, value: &T) -> Result<Value>
422 where
423 T: ?Sized + std::fmt::Display,
424 {
425 Ok(Value::String(value.to_string()))
426 }
427
428 fn is_human_readable(&self) -> bool {
429 true
430 }
431}
432
433fn tagged(tag: Option<Tag>, value: Value) -> Value {
434 match tag {
435 Some(tag) => Value::Tagged(Box::new(TaggedValue { tag, value })),
436 None => value,
437 }
438}
439
440struct TaggedPayload<'a>(&'a TaggedValue);
441
442impl Serialize for TaggedPayload<'_> {
443 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
444 where
445 S: serde::Serializer,
446 {
447 let mut tuple = serializer.serialize_tuple(2)?;
448 tuple.serialize_element(&self.0.tag.to_string())?;
449 tuple.serialize_element(&self.0.value)?;
450 tuple.end()
451 }
452}
453
454impl Serialize for Value {
455 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
456 where
457 S: serde::Serializer,
458 {
459 match self {
460 Self::Null => serializer.serialize_unit(),
461 Self::Bool(value) => serializer.serialize_bool(*value),
462 Self::Number(value) => value.serialize(serializer),
463 Self::String(value) => serializer.serialize_str(value),
464 Self::Sequence(values) => values.serialize(serializer),
465 Self::Mapping(mapping) => mapping.serialize(serializer),
466 Self::Tagged(tagged) => {
467 serializer.serialize_newtype_struct(TAGGED_VALUE_TOKEN, &TaggedPayload(tagged))
468 }
469 }
470 }
471}