1 //! YAML Serialization
2 //!
3 //! This module provides YAML serialization with the type `Serializer`.
4
5 use crate::{error, Error, Result};
6 use serde::{ser, serde_if_integer128};
7 use std::{fmt, io, num, str};
8 use yaml_rust::{yaml, Yaml, YamlEmitter};
9
10 pub struct Serializer;
11
12 impl ser::Serializer for Serializer {
13 type Ok = Yaml;
14 type Error = Error;
15
16 type SerializeSeq = SerializeArray;
17 type SerializeTuple = SerializeArray;
18 type SerializeTupleStruct = SerializeArray;
19 type SerializeTupleVariant = SerializeTupleVariant;
20 type SerializeMap = SerializeMap;
21 type SerializeStruct = SerializeStruct;
22 type SerializeStructVariant = SerializeStructVariant;
23
serialize_bool(self, v: bool) -> Result<Yaml>24 fn serialize_bool(self, v: bool) -> Result<Yaml> {
25 Ok(Yaml::Boolean(v))
26 }
27
serialize_i8(self, v: i8) -> Result<Yaml>28 fn serialize_i8(self, v: i8) -> Result<Yaml> {
29 self.serialize_i64(v as i64)
30 }
31
serialize_i16(self, v: i16) -> Result<Yaml>32 fn serialize_i16(self, v: i16) -> Result<Yaml> {
33 self.serialize_i64(v as i64)
34 }
35
serialize_i32(self, v: i32) -> Result<Yaml>36 fn serialize_i32(self, v: i32) -> Result<Yaml> {
37 self.serialize_i64(v as i64)
38 }
39
serialize_i64(self, v: i64) -> Result<Yaml>40 fn serialize_i64(self, v: i64) -> Result<Yaml> {
41 Ok(Yaml::Integer(v))
42 }
43
44 serde_if_integer128! {
45 #[allow(clippy::cast_possible_truncation)]
46 fn serialize_i128(self, v: i128) -> Result<Yaml> {
47 if v <= i64::max_value() as i128 && v >= i64::min_value() as i128 {
48 self.serialize_i64(v as i64)
49 } else {
50 Ok(Yaml::Real(v.to_string()))
51 }
52 }
53 }
54
serialize_u8(self, v: u8) -> Result<Yaml>55 fn serialize_u8(self, v: u8) -> Result<Yaml> {
56 self.serialize_i64(v as i64)
57 }
58
serialize_u16(self, v: u16) -> Result<Yaml>59 fn serialize_u16(self, v: u16) -> Result<Yaml> {
60 self.serialize_i64(v as i64)
61 }
62
serialize_u32(self, v: u32) -> Result<Yaml>63 fn serialize_u32(self, v: u32) -> Result<Yaml> {
64 self.serialize_i64(v as i64)
65 }
66
serialize_u64(self, v: u64) -> Result<Yaml>67 fn serialize_u64(self, v: u64) -> Result<Yaml> {
68 if v <= i64::max_value() as u64 {
69 self.serialize_i64(v as i64)
70 } else {
71 Ok(Yaml::Real(v.to_string()))
72 }
73 }
74
75 serde_if_integer128! {
76 #[allow(clippy::cast_possible_truncation)]
77 fn serialize_u128(self, v: u128) -> Result<Yaml> {
78 if v <= i64::max_value() as u128 {
79 self.serialize_i64(v as i64)
80 } else {
81 Ok(Yaml::Real(v.to_string()))
82 }
83 }
84 }
85
serialize_f32(self, v: f32) -> Result<Yaml>86 fn serialize_f32(self, v: f32) -> Result<Yaml> {
87 self.serialize_f64(v as f64)
88 }
89
serialize_f64(self, v: f64) -> Result<Yaml>90 fn serialize_f64(self, v: f64) -> Result<Yaml> {
91 Ok(Yaml::Real(match v.classify() {
92 num::FpCategory::Infinite if v.is_sign_positive() => ".inf".into(),
93 num::FpCategory::Infinite => "-.inf".into(),
94 num::FpCategory::Nan => ".nan".into(),
95 _ => {
96 let mut buf = vec![];
97 ::dtoa::write(&mut buf, v).unwrap();
98 ::std::str::from_utf8(&buf).unwrap().into()
99 }
100 }))
101 }
102
serialize_char(self, value: char) -> Result<Yaml>103 fn serialize_char(self, value: char) -> Result<Yaml> {
104 Ok(Yaml::String(value.to_string()))
105 }
106
serialize_str(self, value: &str) -> Result<Yaml>107 fn serialize_str(self, value: &str) -> Result<Yaml> {
108 Ok(Yaml::String(value.to_owned()))
109 }
110
serialize_bytes(self, value: &[u8]) -> Result<Yaml>111 fn serialize_bytes(self, value: &[u8]) -> Result<Yaml> {
112 let vec = value.iter().map(|&b| Yaml::Integer(b as i64)).collect();
113 Ok(Yaml::Array(vec))
114 }
115
serialize_unit(self) -> Result<Yaml>116 fn serialize_unit(self) -> Result<Yaml> {
117 Ok(Yaml::Null)
118 }
119
serialize_unit_struct(self, _name: &'static str) -> Result<Yaml>120 fn serialize_unit_struct(self, _name: &'static str) -> Result<Yaml> {
121 self.serialize_unit()
122 }
123
serialize_unit_variant( self, _name: &str, _variant_index: u32, variant: &str, ) -> Result<Yaml>124 fn serialize_unit_variant(
125 self,
126 _name: &str,
127 _variant_index: u32,
128 variant: &str,
129 ) -> Result<Yaml> {
130 Ok(Yaml::String(variant.to_owned()))
131 }
132
serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Yaml> where T: ser::Serialize,133 fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Yaml>
134 where
135 T: ser::Serialize,
136 {
137 value.serialize(self)
138 }
139
serialize_newtype_variant<T: ?Sized>( self, _name: &str, _variant_index: u32, variant: &str, value: &T, ) -> Result<Yaml> where T: ser::Serialize,140 fn serialize_newtype_variant<T: ?Sized>(
141 self,
142 _name: &str,
143 _variant_index: u32,
144 variant: &str,
145 value: &T,
146 ) -> Result<Yaml>
147 where
148 T: ser::Serialize,
149 {
150 Ok(singleton_hash(to_yaml(variant)?, to_yaml(value)?))
151 }
152
serialize_none(self) -> Result<Yaml>153 fn serialize_none(self) -> Result<Yaml> {
154 self.serialize_unit()
155 }
156
serialize_some<V: ?Sized>(self, value: &V) -> Result<Yaml> where V: ser::Serialize,157 fn serialize_some<V: ?Sized>(self, value: &V) -> Result<Yaml>
158 where
159 V: ser::Serialize,
160 {
161 value.serialize(self)
162 }
163
serialize_seq(self, len: Option<usize>) -> Result<SerializeArray>164 fn serialize_seq(self, len: Option<usize>) -> Result<SerializeArray> {
165 let array = match len {
166 None => yaml::Array::new(),
167 Some(len) => yaml::Array::with_capacity(len),
168 };
169 Ok(SerializeArray { array })
170 }
171
serialize_tuple(self, len: usize) -> Result<SerializeArray>172 fn serialize_tuple(self, len: usize) -> Result<SerializeArray> {
173 self.serialize_seq(Some(len))
174 }
175
serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeArray>176 fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeArray> {
177 self.serialize_seq(Some(len))
178 }
179
serialize_tuple_variant( self, _enum: &'static str, _idx: u32, variant: &'static str, len: usize, ) -> Result<SerializeTupleVariant>180 fn serialize_tuple_variant(
181 self,
182 _enum: &'static str,
183 _idx: u32,
184 variant: &'static str,
185 len: usize,
186 ) -> Result<SerializeTupleVariant> {
187 Ok(SerializeTupleVariant {
188 name: variant,
189 array: yaml::Array::with_capacity(len),
190 })
191 }
192
serialize_map(self, _len: Option<usize>) -> Result<SerializeMap>193 fn serialize_map(self, _len: Option<usize>) -> Result<SerializeMap> {
194 Ok(SerializeMap {
195 hash: yaml::Hash::new(),
196 next_key: None,
197 })
198 }
199
serialize_struct(self, _name: &'static str, _len: usize) -> Result<SerializeStruct>200 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<SerializeStruct> {
201 Ok(SerializeStruct {
202 hash: yaml::Hash::new(),
203 })
204 }
205
serialize_struct_variant( self, _enum: &'static str, _idx: u32, variant: &'static str, _len: usize, ) -> Result<SerializeStructVariant>206 fn serialize_struct_variant(
207 self,
208 _enum: &'static str,
209 _idx: u32,
210 variant: &'static str,
211 _len: usize,
212 ) -> Result<SerializeStructVariant> {
213 Ok(SerializeStructVariant {
214 name: variant,
215 hash: yaml::Hash::new(),
216 })
217 }
218 }
219
220 #[doc(hidden)]
221 pub struct SerializeArray {
222 array: yaml::Array,
223 }
224
225 #[doc(hidden)]
226 pub struct SerializeTupleVariant {
227 name: &'static str,
228 array: yaml::Array,
229 }
230
231 #[doc(hidden)]
232 pub struct SerializeMap {
233 hash: yaml::Hash,
234 next_key: Option<yaml::Yaml>,
235 }
236
237 #[doc(hidden)]
238 pub struct SerializeStruct {
239 hash: yaml::Hash,
240 }
241
242 #[doc(hidden)]
243 pub struct SerializeStructVariant {
244 name: &'static str,
245 hash: yaml::Hash,
246 }
247
248 impl ser::SerializeSeq for SerializeArray {
249 type Ok = yaml::Yaml;
250 type Error = Error;
251
serialize_element<T: ?Sized>(&mut self, elem: &T) -> Result<()> where T: ser::Serialize,252 fn serialize_element<T: ?Sized>(&mut self, elem: &T) -> Result<()>
253 where
254 T: ser::Serialize,
255 {
256 self.array.push(to_yaml(elem)?);
257 Ok(())
258 }
259
end(self) -> Result<Yaml>260 fn end(self) -> Result<Yaml> {
261 Ok(Yaml::Array(self.array))
262 }
263 }
264
265 impl ser::SerializeTuple for SerializeArray {
266 type Ok = yaml::Yaml;
267 type Error = Error;
268
serialize_element<T: ?Sized>(&mut self, elem: &T) -> Result<()> where T: ser::Serialize,269 fn serialize_element<T: ?Sized>(&mut self, elem: &T) -> Result<()>
270 where
271 T: ser::Serialize,
272 {
273 ser::SerializeSeq::serialize_element(self, elem)
274 }
275
end(self) -> Result<Yaml>276 fn end(self) -> Result<Yaml> {
277 ser::SerializeSeq::end(self)
278 }
279 }
280
281 impl ser::SerializeTupleStruct for SerializeArray {
282 type Ok = yaml::Yaml;
283 type Error = Error;
284
serialize_field<V: ?Sized>(&mut self, value: &V) -> Result<()> where V: ser::Serialize,285 fn serialize_field<V: ?Sized>(&mut self, value: &V) -> Result<()>
286 where
287 V: ser::Serialize,
288 {
289 ser::SerializeSeq::serialize_element(self, value)
290 }
291
end(self) -> Result<Yaml>292 fn end(self) -> Result<Yaml> {
293 ser::SerializeSeq::end(self)
294 }
295 }
296
297 impl ser::SerializeTupleVariant for SerializeTupleVariant {
298 type Ok = yaml::Yaml;
299 type Error = Error;
300
serialize_field<V: ?Sized>(&mut self, v: &V) -> Result<()> where V: ser::Serialize,301 fn serialize_field<V: ?Sized>(&mut self, v: &V) -> Result<()>
302 where
303 V: ser::Serialize,
304 {
305 self.array.push(to_yaml(v)?);
306 Ok(())
307 }
308
end(self) -> Result<Yaml>309 fn end(self) -> Result<Yaml> {
310 Ok(singleton_hash(to_yaml(self.name)?, Yaml::Array(self.array)))
311 }
312 }
313
314 impl ser::SerializeMap for SerializeMap {
315 type Ok = yaml::Yaml;
316 type Error = Error;
317
serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()> where T: ser::Serialize,318 fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<()>
319 where
320 T: ser::Serialize,
321 {
322 self.next_key = Some(to_yaml(key)?);
323 Ok(())
324 }
325
serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()> where T: ser::Serialize,326 fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<()>
327 where
328 T: ser::Serialize,
329 {
330 match self.next_key.take() {
331 Some(key) => self.hash.insert(key, to_yaml(value)?),
332 None => panic!("serialize_value called before serialize_key"),
333 };
334 Ok(())
335 }
336
serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()> where K: ser::Serialize, V: ser::Serialize,337 fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<()>
338 where
339 K: ser::Serialize,
340 V: ser::Serialize,
341 {
342 self.hash.insert(to_yaml(key)?, to_yaml(value)?);
343 Ok(())
344 }
345
end(self) -> Result<Yaml>346 fn end(self) -> Result<Yaml> {
347 Ok(Yaml::Hash(self.hash))
348 }
349 }
350
351 impl ser::SerializeStruct for SerializeStruct {
352 type Ok = yaml::Yaml;
353 type Error = Error;
354
serialize_field<V: ?Sized>(&mut self, key: &'static str, value: &V) -> Result<()> where V: ser::Serialize,355 fn serialize_field<V: ?Sized>(&mut self, key: &'static str, value: &V) -> Result<()>
356 where
357 V: ser::Serialize,
358 {
359 self.hash.insert(to_yaml(key)?, to_yaml(value)?);
360 Ok(())
361 }
362
end(self) -> Result<Yaml>363 fn end(self) -> Result<Yaml> {
364 Ok(Yaml::Hash(self.hash))
365 }
366 }
367
368 impl ser::SerializeStructVariant for SerializeStructVariant {
369 type Ok = yaml::Yaml;
370 type Error = Error;
371
serialize_field<V: ?Sized>(&mut self, field: &'static str, v: &V) -> Result<()> where V: ser::Serialize,372 fn serialize_field<V: ?Sized>(&mut self, field: &'static str, v: &V) -> Result<()>
373 where
374 V: ser::Serialize,
375 {
376 self.hash.insert(to_yaml(field)?, to_yaml(v)?);
377 Ok(())
378 }
379
end(self) -> Result<Yaml>380 fn end(self) -> Result<Yaml> {
381 Ok(singleton_hash(to_yaml(self.name)?, Yaml::Hash(self.hash)))
382 }
383 }
384
385 /// Serialize the given data structure as YAML into the IO stream.
386 ///
387 /// Serialization can fail if `T`'s implementation of `Serialize` decides to
388 /// return an error.
to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()> where W: io::Write, T: ser::Serialize,389 pub fn to_writer<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
390 where
391 W: io::Write,
392 T: ser::Serialize,
393 {
394 let doc = to_yaml(value)?;
395 let mut writer_adapter = FmtToIoWriter { writer };
396 YamlEmitter::new(&mut writer_adapter)
397 .dump(&doc)
398 .map_err(error::emitter)?;
399 Ok(())
400 }
401
402 /// Serialize the given data structure as a YAML byte vector.
403 ///
404 /// Serialization can fail if `T`'s implementation of `Serialize` decides to
405 /// return an error.
to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>> where T: ser::Serialize,406 pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>>
407 where
408 T: ser::Serialize,
409 {
410 let mut vec = Vec::with_capacity(128);
411 to_writer(&mut vec, value)?;
412 Ok(vec)
413 }
414
415 /// Serialize the given data structure as a String of YAML.
416 ///
417 /// Serialization can fail if `T`'s implementation of `Serialize` decides to
418 /// return an error.
to_string<T: ?Sized>(value: &T) -> Result<String> where T: ser::Serialize,419 pub fn to_string<T: ?Sized>(value: &T) -> Result<String>
420 where
421 T: ser::Serialize,
422 {
423 Ok(String::from_utf8(to_vec(value)?).map_err(error::string_utf8)?)
424 }
425
426 /// The yaml-rust library uses `fmt::Write` intead of `io::Write` so this is a
427 /// simple adapter.
428 struct FmtToIoWriter<W> {
429 writer: W,
430 }
431
432 impl<W> fmt::Write for FmtToIoWriter<W>
433 where
434 W: io::Write,
435 {
write_str(&mut self, s: &str) -> fmt::Result436 fn write_str(&mut self, s: &str) -> fmt::Result {
437 if self.writer.write(s.as_bytes()).is_err() {
438 return Err(fmt::Error);
439 }
440 Ok(())
441 }
442 }
443
to_yaml<T>(elem: T) -> Result<Yaml> where T: ser::Serialize,444 fn to_yaml<T>(elem: T) -> Result<Yaml>
445 where
446 T: ser::Serialize,
447 {
448 elem.serialize(Serializer)
449 }
450
singleton_hash(k: Yaml, v: Yaml) -> Yaml451 fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
452 let mut hash = yaml::Hash::new();
453 hash.insert(k, v);
454 Yaml::Hash(hash)
455 }
456