1use std::{
6 fmt::{self, Display},
7 io,
8 marker::PhantomData,
9 mem, num, str,
10};
11
12use serde::{
13 de::Visitor,
14 ser::{self, Serializer as _},
15};
16
17use crate::{
18 error::{self, Error, ErrorImpl},
19 libyaml,
20 libyaml::emitter::{Emitter, Event, Mapping, Scalar, ScalarStyle, Sequence},
21 value::tagged::{self, MaybeTag},
22};
23
24type Result<T, E = Error> = std::result::Result<T, E>;
25
26pub struct Serializer<W> {
51 depth: usize,
52 state: State,
53 emitter: Emitter<'static>,
54 writer: PhantomData<W>,
55}
56
57enum State {
58 NothingInParticular,
59 CheckForTag,
60 CheckForDuplicateTag,
61 FoundTag(String),
62 AlreadyTagged,
63}
64
65impl<W> Serializer<W>
66where
67 W: io::Write,
68{
69 pub fn new(writer: W) -> Self {
71 let mut emitter = Emitter::new({
72 let writer = Box::new(writer);
73 unsafe { mem::transmute::<Box<dyn io::Write>, Box<dyn io::Write>>(writer) }
74 });
75 emitter.emit(Event::StreamStart).unwrap();
76 Serializer {
77 depth: 0,
78 state: State::NothingInParticular,
79 emitter,
80 writer: PhantomData,
81 }
82 }
83
84 pub fn flush(&mut self) -> Result<()> {
87 self.emitter.flush()?;
88 Ok(())
89 }
90
91 pub fn into_inner(mut self) -> Result<W> {
93 self.emitter.emit(Event::StreamEnd)?;
94 self.emitter.flush()?;
95 let writer = self.emitter.into_inner();
96 Ok(*unsafe { Box::from_raw(Box::into_raw(writer).cast::<W>()) })
97 }
98
99 fn emit_scalar(&mut self, mut scalar: Scalar) -> Result<()> {
100 self.flush_mapping_start()?;
101 if let Some(tag) = self.take_tag() {
102 scalar.tag = Some(tag);
103 }
104 self.value_start()?;
105 self.emitter.emit(Event::Scalar(scalar))?;
106 self.value_end()
107 }
108
109 fn emit_sequence_start(&mut self) -> Result<()> {
110 self.flush_mapping_start()?;
111 self.value_start()?;
112 let tag = self.take_tag();
113 self.emitter.emit(Event::SequenceStart(Sequence {
114 tag,
115 }))?;
116 Ok(())
117 }
118
119 fn emit_sequence_end(&mut self) -> Result<()> {
120 self.emitter.emit(Event::SequenceEnd)?;
121 self.value_end()
122 }
123
124 fn emit_mapping_start(&mut self) -> Result<()> {
125 self.flush_mapping_start()?;
126 self.value_start()?;
127 let tag = self.take_tag();
128 self.emitter.emit(Event::MappingStart(Mapping {
129 tag,
130 }))?;
131 Ok(())
132 }
133
134 fn emit_mapping_end(&mut self) -> Result<()> {
135 self.emitter.emit(Event::MappingEnd)?;
136 self.value_end()
137 }
138
139 fn value_start(&mut self) -> Result<()> {
140 if self.depth == 0 {
141 self.emitter.emit(Event::DocumentStart)?;
142 }
143 self.depth += 1;
144 Ok(())
145 }
146
147 fn value_end(&mut self) -> Result<()> {
148 self.depth -= 1;
149 if self.depth == 0 {
150 self.emitter.emit(Event::DocumentEnd)?;
151 }
152 Ok(())
153 }
154
155 fn take_tag(&mut self) -> Option<String> {
156 let state = mem::replace(&mut self.state, State::NothingInParticular);
157 if let State::FoundTag(mut tag) = state {
158 if !tag.starts_with('!') {
159 tag.insert(0, '!');
160 }
161 Some(tag)
162 } else {
163 self.state = state;
164 None
165 }
166 }
167
168 fn flush_mapping_start(&mut self) -> Result<()> {
169 if let State::CheckForTag = self.state {
170 self.state = State::NothingInParticular;
171 self.emit_mapping_start()?;
172 } else if let State::CheckForDuplicateTag = self.state {
173 self.state = State::NothingInParticular;
174 }
175 Ok(())
176 }
177}
178
179impl<'a, W> ser::Serializer for &'a mut Serializer<W>
180where
181 W: io::Write,
182{
183 type Ok = ();
184 type Error = Error;
185
186 type SerializeSeq = Self;
187 type SerializeTuple = Self;
188 type SerializeTupleStruct = Self;
189 type SerializeTupleVariant = Self;
190 type SerializeMap = Self;
191 type SerializeStruct = Self;
192 type SerializeStructVariant = Self;
193
194 fn serialize_bool(self, v: bool) -> Result<()> {
195 self.emit_scalar(Scalar {
196 tag: None,
197 value: if v { "true" } else { "false" },
198 style: ScalarStyle::Plain,
199 })
200 }
201
202 fn serialize_i8(self, v: i8) -> Result<()> {
203 self.emit_scalar(Scalar {
204 tag: None,
205 value: itoa::Buffer::new().format(v),
206 style: ScalarStyle::Plain,
207 })
208 }
209
210 fn serialize_i16(self, v: i16) -> Result<()> {
211 self.emit_scalar(Scalar {
212 tag: None,
213 value: itoa::Buffer::new().format(v),
214 style: ScalarStyle::Plain,
215 })
216 }
217
218 fn serialize_i32(self, v: i32) -> Result<()> {
219 self.emit_scalar(Scalar {
220 tag: None,
221 value: itoa::Buffer::new().format(v),
222 style: ScalarStyle::Plain,
223 })
224 }
225
226 fn serialize_i64(self, v: i64) -> Result<()> {
227 self.emit_scalar(Scalar {
228 tag: None,
229 value: itoa::Buffer::new().format(v),
230 style: ScalarStyle::Plain,
231 })
232 }
233
234 fn serialize_i128(self, v: i128) -> Result<()> {
235 self.emit_scalar(Scalar {
236 tag: None,
237 value: itoa::Buffer::new().format(v),
238 style: ScalarStyle::Plain,
239 })
240 }
241
242 fn serialize_u8(self, v: u8) -> Result<()> {
243 self.emit_scalar(Scalar {
244 tag: None,
245 value: itoa::Buffer::new().format(v),
246 style: ScalarStyle::Plain,
247 })
248 }
249
250 fn serialize_u16(self, v: u16) -> Result<()> {
251 self.emit_scalar(Scalar {
252 tag: None,
253 value: itoa::Buffer::new().format(v),
254 style: ScalarStyle::Plain,
255 })
256 }
257
258 fn serialize_u32(self, v: u32) -> Result<()> {
259 self.emit_scalar(Scalar {
260 tag: None,
261 value: itoa::Buffer::new().format(v),
262 style: ScalarStyle::Plain,
263 })
264 }
265
266 fn serialize_u64(self, v: u64) -> Result<()> {
267 self.emit_scalar(Scalar {
268 tag: None,
269 value: itoa::Buffer::new().format(v),
270 style: ScalarStyle::Plain,
271 })
272 }
273
274 fn serialize_u128(self, v: u128) -> Result<()> {
275 self.emit_scalar(Scalar {
276 tag: None,
277 value: itoa::Buffer::new().format(v),
278 style: ScalarStyle::Plain,
279 })
280 }
281
282 fn serialize_f32(self, v: f32) -> Result<()> {
283 let mut buffer = ryu::Buffer::new();
284 self.emit_scalar(Scalar {
285 tag: None,
286 value: match v.classify() {
287 num::FpCategory::Infinite if v.is_sign_positive() => ".inf",
288 num::FpCategory::Infinite => "-.inf",
289 num::FpCategory::Nan => ".nan",
290 _ => buffer.format_finite(v),
291 },
292 style: ScalarStyle::Plain,
293 })
294 }
295
296 fn serialize_f64(self, v: f64) -> Result<()> {
297 let mut buffer = ryu::Buffer::new();
298 self.emit_scalar(Scalar {
299 tag: None,
300 value: match v.classify() {
301 num::FpCategory::Infinite if v.is_sign_positive() => ".inf",
302 num::FpCategory::Infinite => "-.inf",
303 num::FpCategory::Nan => ".nan",
304 _ => buffer.format_finite(v),
305 },
306 style: ScalarStyle::Plain,
307 })
308 }
309
310 fn serialize_char(self, value: char) -> Result<()> {
311 self.emit_scalar(Scalar {
312 tag: None,
313 value: value.encode_utf8(&mut [0u8; 4]),
314 style: ScalarStyle::SingleQuoted,
315 })
316 }
317
318 fn serialize_str(self, value: &str) -> Result<()> {
319 struct InferScalarStyle;
320
321 impl<'de> Visitor<'de> for InferScalarStyle {
322 type Value = ScalarStyle;
323
324 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
325 formatter.write_str("I wonder")
326 }
327
328 fn visit_bool<E>(self, _v: bool) -> Result<Self::Value, E> {
329 Ok(ScalarStyle::SingleQuoted)
330 }
331
332 fn visit_i64<E>(self, _v: i64) -> Result<Self::Value, E> {
333 Ok(ScalarStyle::SingleQuoted)
334 }
335
336 fn visit_i128<E>(self, _v: i128) -> Result<Self::Value, E> {
337 Ok(ScalarStyle::SingleQuoted)
338 }
339
340 fn visit_u64<E>(self, _v: u64) -> Result<Self::Value, E> {
341 Ok(ScalarStyle::SingleQuoted)
342 }
343
344 fn visit_u128<E>(self, _v: u128) -> Result<Self::Value, E> {
345 Ok(ScalarStyle::SingleQuoted)
346 }
347
348 fn visit_f64<E>(self, _v: f64) -> Result<Self::Value, E> {
349 Ok(ScalarStyle::SingleQuoted)
350 }
351
352 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
353 Ok(if crate::de::digits_but_not_number(v) {
354 ScalarStyle::SingleQuoted
355 } else {
356 ScalarStyle::Any
357 })
358 }
359
360 fn visit_unit<E>(self) -> Result<Self::Value, E> {
361 Ok(ScalarStyle::SingleQuoted)
362 }
363 }
364
365 let style = if value.contains('\n') {
366 ScalarStyle::Literal
367 } else {
368 let result =
369 crate::de::visit_untagged_scalar(InferScalarStyle, value, None, libyaml::parser::ScalarStyle::Plain);
370 result.unwrap_or(ScalarStyle::Any)
371 };
372
373 self.emit_scalar(Scalar {
374 tag: None,
375 value,
376 style,
377 })
378 }
379
380 fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
381 Err(error::new(ErrorImpl::BytesUnsupported))
382 }
383
384 fn serialize_unit(self) -> Result<()> {
385 self.emit_scalar(Scalar {
386 tag: None,
387 value: "null",
388 style: ScalarStyle::Plain,
389 })
390 }
391
392 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
393 self.serialize_unit()
394 }
395
396 fn serialize_unit_variant(self, _name: &'static str, _variant_index: u32, variant: &'static str) -> Result<()> {
397 self.serialize_str(variant)
398 }
399
400 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
401 where
402 T: ?Sized + ser::Serialize,
403 {
404 value.serialize(self)
405 }
406
407 fn serialize_newtype_variant<T>(
408 self,
409 _name: &'static str,
410 _variant_index: u32,
411 variant: &'static str,
412 value: &T,
413 ) -> Result<()>
414 where
415 T: ?Sized + ser::Serialize,
416 {
417 if let State::FoundTag(_) = self.state {
418 return Err(error::new(ErrorImpl::SerializeNestedEnum));
419 }
420 self.state = State::FoundTag(variant.to_owned());
421 value.serialize(&mut *self)
422 }
423
424 fn serialize_none(self) -> Result<()> {
425 self.serialize_unit()
426 }
427
428 fn serialize_some<V>(self, value: &V) -> Result<()>
429 where
430 V: ?Sized + ser::Serialize,
431 {
432 value.serialize(self)
433 }
434
435 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
436 self.emit_sequence_start()?;
437 Ok(self)
438 }
439
440 fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
441 self.emit_sequence_start()?;
442 Ok(self)
443 }
444
445 fn serialize_tuple_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct> {
446 self.emit_sequence_start()?;
447 Ok(self)
448 }
449
450 fn serialize_tuple_variant(
451 self,
452 _enm: &'static str,
453 _idx: u32,
454 variant: &'static str,
455 _len: usize,
456 ) -> Result<Self::SerializeTupleVariant> {
457 if let State::FoundTag(_) = self.state {
458 return Err(error::new(ErrorImpl::SerializeNestedEnum));
459 }
460 self.state = State::FoundTag(variant.to_owned());
461 self.emit_sequence_start()?;
462 Ok(self)
463 }
464
465 fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
466 if len == Some(1) {
467 self.state = if let State::FoundTag(_) = self.state {
468 self.emit_mapping_start()?;
469 State::CheckForDuplicateTag
470 } else {
471 State::CheckForTag
472 };
473 } else {
474 self.emit_mapping_start()?;
475 }
476 Ok(self)
477 }
478
479 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
480 self.emit_mapping_start()?;
481 Ok(self)
482 }
483
484 fn serialize_struct_variant(
485 self,
486 _enm: &'static str,
487 _idx: u32,
488 variant: &'static str,
489 _len: usize,
490 ) -> Result<Self::SerializeStructVariant> {
491 if let State::FoundTag(_) = self.state {
492 return Err(error::new(ErrorImpl::SerializeNestedEnum));
493 }
494 self.state = State::FoundTag(variant.to_owned());
495 self.emit_mapping_start()?;
496 Ok(self)
497 }
498
499 fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
500 where
501 T: ?Sized + Display,
502 {
503 let string = if let State::CheckForTag | State::CheckForDuplicateTag = self.state {
504 match tagged::check_for_tag(value) {
505 MaybeTag::NotTag(string) => string,
506 MaybeTag::Tag(string) => {
507 return if let State::CheckForDuplicateTag = self.state {
508 Err(error::new(ErrorImpl::SerializeNestedEnum))
509 } else {
510 self.state = State::FoundTag(string);
511 Ok(())
512 };
513 }
514 }
515 } else {
516 value.to_string()
517 };
518
519 self.serialize_str(&string)
520 }
521}
522
523impl<'a, W> ser::SerializeSeq for &'a mut Serializer<W>
524where
525 W: io::Write,
526{
527 type Ok = ();
528 type Error = Error;
529
530 fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
531 where
532 T: ?Sized + ser::Serialize,
533 {
534 elem.serialize(&mut **self)
535 }
536
537 fn end(self) -> Result<()> {
538 self.emit_sequence_end()
539 }
540}
541
542impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
543where
544 W: io::Write,
545{
546 type Ok = ();
547 type Error = Error;
548
549 fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
550 where
551 T: ?Sized + ser::Serialize,
552 {
553 elem.serialize(&mut **self)
554 }
555
556 fn end(self) -> Result<()> {
557 self.emit_sequence_end()
558 }
559}
560
561impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
562where
563 W: io::Write,
564{
565 type Ok = ();
566 type Error = Error;
567
568 fn serialize_field<V>(&mut self, value: &V) -> Result<()>
569 where
570 V: ?Sized + ser::Serialize,
571 {
572 value.serialize(&mut **self)
573 }
574
575 fn end(self) -> Result<()> {
576 self.emit_sequence_end()
577 }
578}
579
580impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
581where
582 W: io::Write,
583{
584 type Ok = ();
585 type Error = Error;
586
587 fn serialize_field<V>(&mut self, v: &V) -> Result<()>
588 where
589 V: ?Sized + ser::Serialize,
590 {
591 v.serialize(&mut **self)
592 }
593
594 fn end(self) -> Result<()> {
595 self.emit_sequence_end()
596 }
597}
598
599impl<'a, W> ser::SerializeMap for &'a mut Serializer<W>
600where
601 W: io::Write,
602{
603 type Ok = ();
604 type Error = Error;
605
606 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
607 where
608 T: ?Sized + ser::Serialize,
609 {
610 self.flush_mapping_start()?;
611 key.serialize(&mut **self)
612 }
613
614 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
615 where
616 T: ?Sized + ser::Serialize,
617 {
618 value.serialize(&mut **self)
619 }
620
621 fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
622 where
623 K: ?Sized + ser::Serialize,
624 V: ?Sized + ser::Serialize,
625 {
626 key.serialize(&mut **self)?;
627 let tagged = matches!(self.state, State::FoundTag(_));
628 value.serialize(&mut **self)?;
629 if tagged {
630 self.state = State::AlreadyTagged;
631 }
632 Ok(())
633 }
634
635 fn end(self) -> Result<()> {
636 if let State::CheckForTag = self.state {
637 self.emit_mapping_start()?;
638 }
639 if !matches!(self.state, State::AlreadyTagged) {
640 self.emit_mapping_end()?;
641 }
642 self.state = State::NothingInParticular;
643 Ok(())
644 }
645}
646
647impl<'a, W> ser::SerializeStruct for &'a mut Serializer<W>
648where
649 W: io::Write,
650{
651 type Ok = ();
652 type Error = Error;
653
654 fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
655 where
656 V: ?Sized + ser::Serialize,
657 {
658 self.serialize_str(key)?;
659 value.serialize(&mut **self)
660 }
661
662 fn end(self) -> Result<()> {
663 self.emit_mapping_end()
664 }
665}
666
667impl<'a, W> ser::SerializeStructVariant for &'a mut Serializer<W>
668where
669 W: io::Write,
670{
671 type Ok = ();
672 type Error = Error;
673
674 fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
675 where
676 V: ?Sized + ser::Serialize,
677 {
678 self.serialize_str(field)?;
679 v.serialize(&mut **self)
680 }
681
682 fn end(self) -> Result<()> {
683 self.emit_mapping_end()
684 }
685}
686
687pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
692where
693 W: io::Write,
694 T: ?Sized + ser::Serialize,
695{
696 let mut serializer = Serializer::new(writer);
697 value.serialize(&mut serializer)
698}
699
700pub fn to_string<T>(value: &T) -> Result<String>
705where
706 T: ?Sized + ser::Serialize,
707{
708 let mut vec = Vec::with_capacity(128);
709 to_writer(&mut vec, value)?;
710 String::from_utf8(vec).map_err(|error| error::new(ErrorImpl::FromUtf8(error)))
711}