1#[cfg(feature = "alloc")]
4use alloc::vec::Vec;
5
6#[cfg(feature = "std")]
7pub use crate::write::IoWrite;
8pub use crate::write::{SliceWrite, Write};
9
10use crate::error::{Error, Result};
11use half::f16;
12use serde::ser::{self, Serialize};
13#[cfg(feature = "std")]
14use std::io;
15
16use crate::tags::{get_tag, CBOR_NEWTYPE_NAME};
17
18#[cfg(any(feature = "std", feature = "alloc"))]
20pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
21where
22 T: ser::Serialize,
23{
24 let mut vec = Vec::new();
25 value.serialize(&mut Serializer::new(&mut vec))?;
26 Ok(vec)
27}
28
29#[cfg(feature = "std")]
31pub fn to_vec_packed<T>(value: &T) -> Result<Vec<u8>>
32where
33 T: ser::Serialize,
34{
35 let mut vec = Vec::new();
36 value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).packed_format())?;
37 Ok(vec)
38}
39
40#[cfg(feature = "std")]
42pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
43where
44 W: io::Write,
45 T: ser::Serialize,
46{
47 value.serialize(&mut Serializer::new(&mut IoWrite::new(writer)))
48}
49
50#[derive(Debug)]
52pub struct Serializer<W> {
53 writer: W,
54 packed: bool,
55 enum_as_map: bool,
56}
57
58impl<W> Serializer<W>
59where
60 W: Write,
61{
62 #[inline]
66 pub const fn new(writer: W) -> Self {
67 Self {
68 writer,
69 packed: false,
70 enum_as_map: true,
71 }
72 }
73
74 #[must_use]
79 pub const fn packed_format(mut self) -> Self {
80 self.packed = true;
81 self
82 }
83
84 #[must_use]
120 pub const fn legacy_enums(mut self) -> Self {
121 self.enum_as_map = false;
122 self
123 }
124
125 #[inline]
130 pub fn self_describe(&mut self) -> Result<()> {
131 let mut buf = [6 << 5 | 25, 0, 0];
132 buf[1..].copy_from_slice(&55799u16.to_be_bytes());
133 self.writer
134 .write_all(&buf)
135 .map_err(core::convert::Into::into)
136 }
137
138 #[inline]
140 pub fn into_inner(self) -> W {
141 self.writer
142 }
143
144 #[inline]
145 fn write_u8(&mut self, major: u8, value: u8) -> Result<()> {
146 if value <= 0x17 {
147 self.writer.write_all(&[major << 5 | value])
148 } else {
149 let buf = [major << 5 | 24, value];
150 self.writer.write_all(&buf)
151 }
152 .map_err(core::convert::Into::into)
153 }
154
155 #[inline]
156 fn write_u16(&mut self, major: u8, value: u16) -> Result<()> {
157 if u8::try_from(value).is_ok() {
158 self.write_u8(major, value as u8)
159 } else {
160 let mut buf = [major << 5 | 25, 0, 0];
161 buf[1..].copy_from_slice(&value.to_be_bytes());
162 self.writer
163 .write_all(&buf)
164 .map_err(core::convert::Into::into)
165 }
166 }
167
168 #[inline]
169 fn write_u32(&mut self, major: u8, value: u32) -> Result<()> {
170 if u16::try_from(value).is_ok() {
171 self.write_u16(major, value as u16)
172 } else {
173 let mut buf = [major << 5 | 26, 0, 0, 0, 0];
174 buf[1..].copy_from_slice(&value.to_be_bytes());
175 self.writer
176 .write_all(&buf)
177 .map_err(core::convert::Into::into)
178 }
179 }
180
181 #[inline]
182 fn write_u64(&mut self, major: u8, value: u64) -> Result<()> {
183 if u32::try_from(value).is_ok() {
184 self.write_u32(major, value as u32)
185 } else {
186 let mut buf = [major << 5 | 27, 0, 0, 0, 0, 0, 0, 0, 0];
187 buf[1..].copy_from_slice(&value.to_be_bytes());
188 self.writer
189 .write_all(&buf)
190 .map_err(core::convert::Into::into)
191 }
192 }
193
194 #[inline]
195 fn serialize_collection(
196 &mut self,
197 major: u8,
198 len: Option<usize>,
199 ) -> Result<CollectionSerializer<'_, W>> {
200 let needs_eof = if let Some(len) = len {
201 self.write_u64(major, len as u64)?;
202 false
203 } else {
204 self.writer
205 .write_all(&[major << 5 | 31])
206 .map_err(core::convert::Into::into)?;
207 true
208 };
209
210 Ok(CollectionSerializer {
211 ser: self,
212 needs_eof,
213 })
214 }
215}
216
217impl<'a, W> ser::Serializer for &'a mut Serializer<W>
218where
219 W: Write,
220{
221 type Ok = ();
222 type Error = Error;
223
224 type SerializeSeq = CollectionSerializer<'a, W>;
225 type SerializeTuple = &'a mut Serializer<W>;
226 type SerializeTupleStruct = &'a mut Serializer<W>;
227 type SerializeTupleVariant = &'a mut Serializer<W>;
228 type SerializeMap = CollectionSerializer<'a, W>;
229 type SerializeStruct = StructSerializer<'a, W>;
230 type SerializeStructVariant = StructSerializer<'a, W>;
231
232 #[inline]
233 fn serialize_bool(self, value: bool) -> Result<()> {
234 let value = if value { 0xf5 } else { 0xf4 };
235 self.writer
236 .write_all(&[value])
237 .map_err(core::convert::Into::into)
238 }
239
240 #[inline]
241 fn serialize_i8(self, value: i8) -> Result<()> {
242 if value < 0 {
243 self.write_u8(1, -(value + 1) as u8)
244 } else {
245 self.write_u8(0, value as u8)
246 }
247 }
248
249 #[inline]
250 fn serialize_i16(self, value: i16) -> Result<()> {
251 if value < 0 {
252 self.write_u16(1, -(value + 1) as u16)
253 } else {
254 self.write_u16(0, value as u16)
255 }
256 }
257
258 #[inline]
259 fn serialize_i32(self, value: i32) -> Result<()> {
260 if value < 0 {
261 self.write_u32(1, -(value + 1) as u32)
262 } else {
263 self.write_u32(0, value as u32)
264 }
265 }
266
267 #[inline]
268 fn serialize_i64(self, value: i64) -> Result<()> {
269 if value < 0 {
270 self.write_u64(1, -(value + 1) as u64)
271 } else {
272 self.write_u64(0, value as u64)
273 }
274 }
275
276 #[inline]
277 fn serialize_i128(self, value: i128) -> Result<()> {
278 if value < 0 {
279 if -(value + 1) > i128::from(u64::MAX) {
280 return Err(Error::message("The number can't be stored in CBOR"));
281 }
282 self.write_u64(1, -(value + 1) as u64)
283 } else {
284 if value > i128::from(u64::MAX) {
285 return Err(Error::message("The number can't be stored in CBOR"));
286 }
287 self.write_u64(0, value as u64)
288 }
289 }
290
291 #[inline]
292 fn serialize_u8(self, value: u8) -> Result<()> {
293 self.write_u8(0, value)
294 }
295
296 #[inline]
297 fn serialize_u16(self, value: u16) -> Result<()> {
298 self.write_u16(0, value)
299 }
300
301 #[inline]
302 fn serialize_u32(self, value: u32) -> Result<()> {
303 self.write_u32(0, value)
304 }
305
306 #[inline]
307 fn serialize_u64(self, value: u64) -> Result<()> {
308 self.write_u64(0, value)
309 }
310
311 #[inline]
312 fn serialize_u128(self, value: u128) -> Result<()> {
313 if value > u128::from(u64::MAX) {
314 return Err(Error::message("The number can't be stored in CBOR"));
315 }
316 self.write_u64(0, value as u64)
317 }
318
319 #[inline]
320 #[allow(clippy::float_cmp)]
321 fn serialize_f32(self, value: f32) -> Result<()> {
322 if value.is_infinite() {
323 if value.is_sign_positive() {
324 self.writer.write_all(&[0xf9, 0x7c, 0x00])
325 } else {
326 self.writer.write_all(&[0xf9, 0xfc, 0x00])
327 }
328 } else if value.is_nan() {
329 self.writer.write_all(&[0xf9, 0x7e, 0x00])
330 } else if f32::from(f16::from_f32(value)) == value {
331 let mut buf = [0xf9, 0, 0];
332 buf[1..].copy_from_slice(&f16::from_f32(value).to_bits().to_be_bytes());
333 self.writer.write_all(&buf)
334 } else {
335 let mut buf = [0xfa, 0, 0, 0, 0];
336 buf[1..].copy_from_slice(&value.to_bits().to_be_bytes());
337 self.writer.write_all(&buf)
338 }
339 .map_err(core::convert::Into::into)
340 }
341
342 #[inline]
343 #[allow(clippy::float_cmp)]
344 fn serialize_f64(self, value: f64) -> Result<()> {
345 if !value.is_finite() || f64::from(value as f32) == value {
346 self.serialize_f32(value as f32)
347 } else {
348 let mut buf = [0xfb, 0, 0, 0, 0, 0, 0, 0, 0];
349 buf[1..].copy_from_slice(&value.to_bits().to_be_bytes());
350 self.writer
351 .write_all(&buf)
352 .map_err(core::convert::Into::into)
353 }
354 }
355
356 #[inline]
357 fn serialize_char(self, value: char) -> Result<()> {
358 let mut buf = [0; 4];
360 self.serialize_str(value.encode_utf8(&mut buf))
361 }
362
363 #[inline]
364 fn serialize_str(self, value: &str) -> Result<()> {
365 self.write_u64(3, value.len() as u64)?;
366 self.writer
367 .write_all(value.as_bytes())
368 .map_err(core::convert::Into::into)
369 }
370
371 #[inline]
372 fn serialize_bytes(self, value: &[u8]) -> Result<()> {
373 self.write_u64(2, value.len() as u64)?;
374 self.writer
375 .write_all(value)
376 .map_err(core::convert::Into::into)
377 }
378
379 #[inline]
380 fn serialize_unit(self) -> Result<()> {
381 self.serialize_none()
382 }
383
384 #[inline]
385 fn serialize_some<T>(self, value: &T) -> Result<()>
386 where
387 T: ?Sized + ser::Serialize,
388 {
389 value.serialize(self)
390 }
391
392 #[inline]
393 fn serialize_none(self) -> Result<()> {
394 self.writer
395 .write_all(&[0xf6])
396 .map_err(core::convert::Into::into)
397 }
398
399 #[inline]
400 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
401 self.serialize_unit()
402 }
403
404 #[inline]
405 fn serialize_unit_variant(
406 self,
407 _name: &'static str,
408 variant_index: u32,
409 variant: &'static str,
410 ) -> Result<()> {
411 if self.packed {
412 self.serialize_u32(variant_index)
413 } else {
414 self.serialize_str(variant)
415 }
416 }
417
418 #[inline]
419 fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
420 where
421 T: ?Sized + ser::Serialize,
422 {
423 if name == CBOR_NEWTYPE_NAME {
424 if let Some(tag) = get_tag() {
425 self.write_u64(6, tag)?;
426 }
427 }
428 value.serialize(self)
429 }
430
431 #[inline]
432 fn serialize_newtype_variant<T>(
433 self,
434 name: &'static str,
435 variant_index: u32,
436 variant: &'static str,
437 value: &T,
438 ) -> Result<()>
439 where
440 T: ?Sized + ser::Serialize,
441 {
442 if self.enum_as_map {
443 self.write_u64(5, 1u64)?;
444 variant.serialize(&mut *self)?;
445 } else {
446 self.writer
447 .write_all(&[4 << 5 | 2])
448 .map_err(core::convert::Into::into)?;
449 self.serialize_unit_variant(name, variant_index, variant)?;
450 }
451 value.serialize(self)
452 }
453
454 #[inline]
455 fn serialize_seq(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
456 self.serialize_collection(4, len)
457 }
458
459 #[inline]
460 fn serialize_tuple(self, len: usize) -> Result<&'a mut Serializer<W>> {
461 self.write_u64(4, len as u64)?;
462 Ok(self)
463 }
464
465 #[inline]
466 fn serialize_tuple_struct(
467 self,
468 _name: &'static str,
469 len: usize,
470 ) -> Result<&'a mut Serializer<W>> {
471 self.serialize_tuple(len)
472 }
473
474 #[inline]
475 fn serialize_tuple_variant(
476 self,
477 name: &'static str,
478 variant_index: u32,
479 variant: &'static str,
480 len: usize,
481 ) -> Result<&'a mut Serializer<W>> {
482 if self.enum_as_map {
483 self.write_u64(5, 1u64)?;
484 variant.serialize(&mut *self)?;
485 self.serialize_tuple(len)
486 } else {
487 self.write_u64(4, (len + 1) as u64)?;
488 self.serialize_unit_variant(name, variant_index, variant)?;
489 Ok(self)
490 }
491 }
492
493 #[inline]
494 fn serialize_map(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
495 self.serialize_collection(5, len)
496 }
497
498 #[cfg(not(feature = "std"))]
499 fn collect_str<T: ?Sized + core::fmt::Display>(self, value: &T) -> Result<()> {
500 use crate::write::FmtWrite;
501 use core::fmt::Write;
502
503 let mut w = FmtWrite::new(&mut self.writer);
504 write!(w, "{value}")?;
505 Ok(())
506 }
507
508 #[inline]
509 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<StructSerializer<'a, W>> {
510 self.write_u64(5, len as u64)?;
511 Ok(StructSerializer { ser: self, idx: 0 })
512 }
513
514 #[inline]
515 fn serialize_struct_variant(
516 self,
517 name: &'static str,
518 variant_index: u32,
519 variant: &'static str,
520 len: usize,
521 ) -> Result<StructSerializer<'a, W>> {
522 if self.enum_as_map {
523 self.write_u64(5, 1u64)?;
524 } else {
525 self.writer
526 .write_all(&[4 << 5 | 2])
527 .map_err(core::convert::Into::into)?;
528 }
529 self.serialize_unit_variant(name, variant_index, variant)?;
530 self.serialize_struct(name, len)
531 }
532
533 #[inline]
534 fn is_human_readable(&self) -> bool {
535 false
536 }
537}
538
539impl<W> ser::SerializeTuple for &mut Serializer<W>
540where
541 W: Write,
542{
543 type Ok = ();
544 type Error = Error;
545
546 #[inline]
547 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
548 where
549 T: ?Sized + ser::Serialize,
550 {
551 value.serialize(&mut **self)
552 }
553
554 #[inline]
555 fn end(self) -> Result<()> {
556 Ok(())
557 }
558}
559
560impl<W> ser::SerializeTupleStruct for &mut Serializer<W>
561where
562 W: Write,
563{
564 type Ok = ();
565 type Error = Error;
566
567 #[inline]
568 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
569 where
570 T: ?Sized + ser::Serialize,
571 {
572 value.serialize(&mut **self)
573 }
574
575 #[inline]
576 fn end(self) -> Result<()> {
577 Ok(())
578 }
579}
580
581impl<W> ser::SerializeTupleVariant for &mut Serializer<W>
582where
583 W: Write,
584{
585 type Ok = ();
586 type Error = Error;
587
588 #[inline]
589 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
590 where
591 T: ?Sized + ser::Serialize,
592 {
593 value.serialize(&mut **self)
594 }
595
596 #[inline]
597 fn end(self) -> Result<()> {
598 Ok(())
599 }
600}
601
602#[doc(hidden)]
603pub struct StructSerializer<'a, W> {
604 ser: &'a mut Serializer<W>,
605 idx: u32,
606}
607
608impl<W> StructSerializer<'_, W>
609where
610 W: Write,
611{
612 #[inline]
613 fn serialize_field_inner<T>(&mut self, key: &'static str, value: &T) -> Result<()>
614 where
615 T: ?Sized + ser::Serialize,
616 {
617 if self.ser.packed {
618 self.idx.serialize(&mut *self.ser)?;
619 } else {
620 key.serialize(&mut *self.ser)?;
621 }
622 value.serialize(&mut *self.ser)?;
623 self.idx += 1;
624 Ok(())
625 }
626
627 #[inline]
628 const fn skip_field_inner(&mut self, _key: &'static str) {
629 self.idx += 1;
630 }
631
632 #[inline]
633 #[allow(clippy::unused_self)] const fn end_inner(self) {
635 }
638}
639
640impl<W> ser::SerializeStruct for StructSerializer<'_, W>
641where
642 W: Write,
643{
644 type Ok = ();
645 type Error = Error;
646
647 #[inline]
648 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
649 where
650 T: ?Sized + ser::Serialize,
651 {
652 self.serialize_field_inner(key, value)
653 }
654
655 #[inline]
656 fn skip_field(&mut self, key: &'static str) -> Result<()> {
657 self.skip_field_inner(key);
658 Ok(())
659 }
660
661 #[inline]
662 fn end(self) -> Result<()> {
663 self.end_inner();
664 Ok(())
665 }
666}
667
668impl<W> ser::SerializeStructVariant for StructSerializer<'_, W>
669where
670 W: Write,
671{
672 type Ok = ();
673 type Error = Error;
674
675 #[inline]
676 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
677 where
678 T: ?Sized + ser::Serialize,
679 {
680 self.serialize_field_inner(key, value)
681 }
682
683 #[inline]
684 fn skip_field(&mut self, key: &'static str) -> Result<()> {
685 self.skip_field_inner(key);
686 Ok(())
687 }
688
689 #[inline]
690 fn end(self) -> Result<()> {
691 self.end_inner();
692 Ok(())
693 }
694}
695
696#[doc(hidden)]
697pub struct CollectionSerializer<'a, W> {
698 ser: &'a mut Serializer<W>,
699 needs_eof: bool,
700}
701
702impl<W> CollectionSerializer<'_, W>
703where
704 W: Write,
705{
706 #[inline]
707 fn end_inner(self) -> Result<()> {
708 if self.needs_eof {
709 self.ser
710 .writer
711 .write_all(&[0xff])
712 .map_err(core::convert::Into::into)
713 } else {
714 Ok(())
715 }
716 }
717}
718
719impl<W> ser::SerializeSeq for CollectionSerializer<'_, W>
720where
721 W: Write,
722{
723 type Ok = ();
724 type Error = Error;
725
726 #[inline]
727 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
728 where
729 T: ?Sized + ser::Serialize,
730 {
731 value.serialize(&mut *self.ser)
732 }
733
734 #[inline]
735 fn end(self) -> Result<()> {
736 self.end_inner()
737 }
738}
739
740impl<W> ser::SerializeMap for CollectionSerializer<'_, W>
741where
742 W: Write,
743{
744 type Ok = ();
745 type Error = Error;
746
747 #[inline]
748 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
749 where
750 T: ?Sized + ser::Serialize,
751 {
752 key.serialize(&mut *self.ser)
753 }
754
755 #[inline]
756 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
757 where
758 T: ?Sized + ser::Serialize,
759 {
760 value.serialize(&mut *self.ser)
761 }
762
763 #[inline]
764 fn end(self) -> Result<()> {
765 self.end_inner()
766 }
767}