1 // SPDX-License-Identifier: Apache-2.0
2
3 //! Serde serialization support for CBOR
4
5 mod error;
6
7 pub use error::Error;
8
9 use alloc::string::ToString;
10
11 use ciborium_io::Write;
12 use ciborium_ll::*;
13 use serde::{ser, Serialize as _};
14
15 struct Serializer<W: Write>(Encoder<W>);
16
17 impl<W: Write> From<W> for Serializer<W> {
18 #[inline]
from(writer: W) -> Self19 fn from(writer: W) -> Self {
20 Self(writer.into())
21 }
22 }
23
24 impl<W: Write> From<Encoder<W>> for Serializer<W> {
25 #[inline]
from(writer: Encoder<W>) -> Self26 fn from(writer: Encoder<W>) -> Self {
27 Self(writer)
28 }
29 }
30
31 impl<'a, W: Write> ser::Serializer for &'a mut Serializer<W>
32 where
33 W::Error: core::fmt::Debug,
34 {
35 type Ok = ();
36 type Error = Error<W::Error>;
37
38 type SerializeSeq = CollectionSerializer<'a, W>;
39 type SerializeTuple = CollectionSerializer<'a, W>;
40 type SerializeTupleStruct = CollectionSerializer<'a, W>;
41 type SerializeTupleVariant = CollectionSerializer<'a, W>;
42 type SerializeMap = CollectionSerializer<'a, W>;
43 type SerializeStruct = CollectionSerializer<'a, W>;
44 type SerializeStructVariant = CollectionSerializer<'a, W>;
45
46 #[inline]
serialize_bool(self, v: bool) -> Result<(), Self::Error>47 fn serialize_bool(self, v: bool) -> Result<(), Self::Error> {
48 Ok(self.0.push(match v {
49 false => Header::Simple(simple::FALSE),
50 true => Header::Simple(simple::TRUE),
51 })?)
52 }
53
54 #[inline]
serialize_i8(self, v: i8) -> Result<(), Self::Error>55 fn serialize_i8(self, v: i8) -> Result<(), Self::Error> {
56 self.serialize_i64(v.into())
57 }
58
59 #[inline]
serialize_i16(self, v: i16) -> Result<(), Self::Error>60 fn serialize_i16(self, v: i16) -> Result<(), Self::Error> {
61 self.serialize_i64(v.into())
62 }
63
64 #[inline]
serialize_i32(self, v: i32) -> Result<(), Self::Error>65 fn serialize_i32(self, v: i32) -> Result<(), Self::Error> {
66 self.serialize_i64(v.into())
67 }
68
69 #[inline]
serialize_i64(self, v: i64) -> Result<(), Self::Error>70 fn serialize_i64(self, v: i64) -> Result<(), Self::Error> {
71 Ok(self.0.push(match v.is_negative() {
72 false => Header::Positive(v as u64),
73 true => Header::Negative(v as u64 ^ !0),
74 })?)
75 }
76
77 #[inline]
serialize_i128(self, v: i128) -> Result<(), Self::Error>78 fn serialize_i128(self, v: i128) -> Result<(), Self::Error> {
79 let (tag, raw) = match v.is_negative() {
80 false => (tag::BIGPOS, v as u128),
81 true => (tag::BIGNEG, v as u128 ^ !0),
82 };
83
84 match (tag, u64::try_from(raw)) {
85 (tag::BIGPOS, Ok(x)) => return Ok(self.0.push(Header::Positive(x))?),
86 (tag::BIGNEG, Ok(x)) => return Ok(self.0.push(Header::Negative(x))?),
87 _ => {}
88 }
89
90 let bytes = raw.to_be_bytes();
91
92 // Skip leading zeros.
93 let mut slice = &bytes[..];
94 while !slice.is_empty() && slice[0] == 0 {
95 slice = &slice[1..];
96 }
97
98 self.0.push(Header::Tag(tag))?;
99 self.0.push(Header::Bytes(Some(slice.len())))?;
100 Ok(self.0.write_all(slice)?)
101 }
102
103 #[inline]
serialize_u8(self, v: u8) -> Result<(), Self::Error>104 fn serialize_u8(self, v: u8) -> Result<(), Self::Error> {
105 self.serialize_u64(v.into())
106 }
107
108 #[inline]
serialize_u16(self, v: u16) -> Result<(), Self::Error>109 fn serialize_u16(self, v: u16) -> Result<(), Self::Error> {
110 self.serialize_u64(v.into())
111 }
112
113 #[inline]
serialize_u32(self, v: u32) -> Result<(), Self::Error>114 fn serialize_u32(self, v: u32) -> Result<(), Self::Error> {
115 self.serialize_u64(v.into())
116 }
117
118 #[inline]
serialize_u64(self, v: u64) -> Result<(), Self::Error>119 fn serialize_u64(self, v: u64) -> Result<(), Self::Error> {
120 Ok(self.0.push(Header::Positive(v))?)
121 }
122
123 #[inline]
serialize_u128(self, v: u128) -> Result<(), Self::Error>124 fn serialize_u128(self, v: u128) -> Result<(), Self::Error> {
125 if let Ok(x) = u64::try_from(v) {
126 return self.serialize_u64(x);
127 }
128
129 let bytes = v.to_be_bytes();
130
131 // Skip leading zeros.
132 let mut slice = &bytes[..];
133 while !slice.is_empty() && slice[0] == 0 {
134 slice = &slice[1..];
135 }
136
137 self.0.push(Header::Tag(tag::BIGPOS))?;
138 self.0.push(Header::Bytes(Some(slice.len())))?;
139 Ok(self.0.write_all(slice)?)
140 }
141
142 #[inline]
serialize_f32(self, v: f32) -> Result<(), Self::Error>143 fn serialize_f32(self, v: f32) -> Result<(), Self::Error> {
144 self.serialize_f64(v.into())
145 }
146
147 #[inline]
serialize_f64(self, v: f64) -> Result<(), Self::Error>148 fn serialize_f64(self, v: f64) -> Result<(), Self::Error> {
149 Ok(self.0.push(Header::Float(v))?)
150 }
151
152 #[inline]
serialize_char(self, v: char) -> Result<(), Self::Error>153 fn serialize_char(self, v: char) -> Result<(), Self::Error> {
154 self.serialize_str(&v.to_string())
155 }
156
157 #[inline]
serialize_str(self, v: &str) -> Result<(), Self::Error>158 fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
159 let bytes = v.as_bytes();
160 self.0.push(Header::Text(bytes.len().into()))?;
161 Ok(self.0.write_all(bytes)?)
162 }
163
164 #[inline]
serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error>165 fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
166 self.0.push(Header::Bytes(v.len().into()))?;
167 Ok(self.0.write_all(v)?)
168 }
169
170 #[inline]
serialize_none(self) -> Result<(), Self::Error>171 fn serialize_none(self) -> Result<(), Self::Error> {
172 Ok(self.0.push(Header::Simple(simple::NULL))?)
173 }
174
175 #[inline]
serialize_some<U: ?Sized + ser::Serialize>(self, value: &U) -> Result<(), Self::Error>176 fn serialize_some<U: ?Sized + ser::Serialize>(self, value: &U) -> Result<(), Self::Error> {
177 value.serialize(self)
178 }
179
180 #[inline]
serialize_unit(self) -> Result<(), Self::Error>181 fn serialize_unit(self) -> Result<(), Self::Error> {
182 self.serialize_none()
183 }
184
185 #[inline]
serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error>186 fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> {
187 self.serialize_unit()
188 }
189
190 #[inline]
serialize_unit_variant( self, _name: &'static str, _index: u32, variant: &'static str, ) -> Result<(), Self::Error>191 fn serialize_unit_variant(
192 self,
193 _name: &'static str,
194 _index: u32,
195 variant: &'static str,
196 ) -> Result<(), Self::Error> {
197 self.serialize_str(variant)
198 }
199
200 #[inline]
serialize_newtype_struct<U: ?Sized + ser::Serialize>( self, _name: &'static str, value: &U, ) -> Result<(), Self::Error>201 fn serialize_newtype_struct<U: ?Sized + ser::Serialize>(
202 self,
203 _name: &'static str,
204 value: &U,
205 ) -> Result<(), Self::Error> {
206 value.serialize(self)
207 }
208
209 #[inline]
serialize_newtype_variant<U: ?Sized + ser::Serialize>( self, name: &'static str, _index: u32, variant: &'static str, value: &U, ) -> Result<(), Self::Error>210 fn serialize_newtype_variant<U: ?Sized + ser::Serialize>(
211 self,
212 name: &'static str,
213 _index: u32,
214 variant: &'static str,
215 value: &U,
216 ) -> Result<(), Self::Error> {
217 if name != "@@TAG@@" || variant != "@@UNTAGGED@@" {
218 self.0.push(Header::Map(Some(1)))?;
219 self.serialize_str(variant)?;
220 }
221
222 value.serialize(self)
223 }
224
225 #[inline]
serialize_seq(self, length: Option<usize>) -> Result<Self::SerializeSeq, Self::Error>226 fn serialize_seq(self, length: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
227 self.0.push(Header::Array(length))?;
228 Ok(CollectionSerializer {
229 encoder: self,
230 ending: length.is_none(),
231 tag: false,
232 })
233 }
234
235 #[inline]
serialize_tuple(self, length: usize) -> Result<Self::SerializeTuple, Self::Error>236 fn serialize_tuple(self, length: usize) -> Result<Self::SerializeTuple, Self::Error> {
237 self.serialize_seq(Some(length))
238 }
239
240 #[inline]
serialize_tuple_struct( self, _name: &'static str, length: usize, ) -> Result<Self::SerializeTupleStruct, Self::Error>241 fn serialize_tuple_struct(
242 self,
243 _name: &'static str,
244 length: usize,
245 ) -> Result<Self::SerializeTupleStruct, Self::Error> {
246 self.serialize_seq(Some(length))
247 }
248
249 #[inline]
serialize_tuple_variant( self, name: &'static str, _index: u32, variant: &'static str, length: usize, ) -> Result<Self::SerializeTupleVariant, Self::Error>250 fn serialize_tuple_variant(
251 self,
252 name: &'static str,
253 _index: u32,
254 variant: &'static str,
255 length: usize,
256 ) -> Result<Self::SerializeTupleVariant, Self::Error> {
257 match (name, variant) {
258 ("@@TAG@@", "@@TAGGED@@") => Ok(CollectionSerializer {
259 encoder: self,
260 ending: false,
261 tag: true,
262 }),
263
264 _ => {
265 self.0.push(Header::Map(Some(1)))?;
266 self.serialize_str(variant)?;
267 self.0.push(Header::Array(Some(length)))?;
268 Ok(CollectionSerializer {
269 encoder: self,
270 ending: false,
271 tag: false,
272 })
273 }
274 }
275 }
276
277 #[inline]
serialize_map(self, length: Option<usize>) -> Result<Self::SerializeMap, Self::Error>278 fn serialize_map(self, length: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
279 self.0.push(Header::Map(length))?;
280 Ok(CollectionSerializer {
281 encoder: self,
282 ending: length.is_none(),
283 tag: false,
284 })
285 }
286
287 #[inline]
serialize_struct( self, _name: &'static str, length: usize, ) -> Result<Self::SerializeStruct, Self::Error>288 fn serialize_struct(
289 self,
290 _name: &'static str,
291 length: usize,
292 ) -> Result<Self::SerializeStruct, Self::Error> {
293 self.0.push(Header::Map(Some(length)))?;
294 Ok(CollectionSerializer {
295 encoder: self,
296 ending: false,
297 tag: false,
298 })
299 }
300
301 #[inline]
serialize_struct_variant( self, _name: &'static str, _index: u32, variant: &'static str, length: usize, ) -> Result<Self::SerializeStructVariant, Self::Error>302 fn serialize_struct_variant(
303 self,
304 _name: &'static str,
305 _index: u32,
306 variant: &'static str,
307 length: usize,
308 ) -> Result<Self::SerializeStructVariant, Self::Error> {
309 self.0.push(Header::Map(Some(1)))?;
310 self.serialize_str(variant)?;
311 self.0.push(Header::Map(Some(length)))?;
312 Ok(CollectionSerializer {
313 encoder: self,
314 ending: false,
315 tag: false,
316 })
317 }
318
319 #[inline]
is_human_readable(&self) -> bool320 fn is_human_readable(&self) -> bool {
321 false
322 }
323 }
324
325 macro_rules! end {
326 () => {
327 #[inline]
328 fn end(self) -> Result<(), Self::Error> {
329 if self.ending {
330 self.encoder.0.push(Header::Break)?;
331 }
332
333 Ok(())
334 }
335 };
336 }
337
338 struct CollectionSerializer<'a, W: Write> {
339 encoder: &'a mut Serializer<W>,
340 ending: bool,
341 tag: bool,
342 }
343
344 impl<'a, W: Write> ser::SerializeSeq for CollectionSerializer<'a, W>
345 where
346 W::Error: core::fmt::Debug,
347 {
348 type Ok = ();
349 type Error = Error<W::Error>;
350
351 #[inline]
serialize_element<U: ?Sized + ser::Serialize>( &mut self, value: &U, ) -> Result<(), Self::Error>352 fn serialize_element<U: ?Sized + ser::Serialize>(
353 &mut self,
354 value: &U,
355 ) -> Result<(), Self::Error> {
356 value.serialize(&mut *self.encoder)
357 }
358
359 end!();
360 }
361
362 impl<'a, W: Write> ser::SerializeTuple for CollectionSerializer<'a, W>
363 where
364 W::Error: core::fmt::Debug,
365 {
366 type Ok = ();
367 type Error = Error<W::Error>;
368
369 #[inline]
serialize_element<U: ?Sized + ser::Serialize>( &mut self, value: &U, ) -> Result<(), Self::Error>370 fn serialize_element<U: ?Sized + ser::Serialize>(
371 &mut self,
372 value: &U,
373 ) -> Result<(), Self::Error> {
374 value.serialize(&mut *self.encoder)
375 }
376
377 end!();
378 }
379
380 impl<'a, W: Write> ser::SerializeTupleStruct for CollectionSerializer<'a, W>
381 where
382 W::Error: core::fmt::Debug,
383 {
384 type Ok = ();
385 type Error = Error<W::Error>;
386
387 #[inline]
serialize_field<U: ?Sized + ser::Serialize>( &mut self, value: &U, ) -> Result<(), Self::Error>388 fn serialize_field<U: ?Sized + ser::Serialize>(
389 &mut self,
390 value: &U,
391 ) -> Result<(), Self::Error> {
392 value.serialize(&mut *self.encoder)
393 }
394
395 end!();
396 }
397
398 impl<'a, W: Write> ser::SerializeTupleVariant for CollectionSerializer<'a, W>
399 where
400 W::Error: core::fmt::Debug,
401 {
402 type Ok = ();
403 type Error = Error<W::Error>;
404
405 #[inline]
serialize_field<U: ?Sized + ser::Serialize>( &mut self, value: &U, ) -> Result<(), Self::Error>406 fn serialize_field<U: ?Sized + ser::Serialize>(
407 &mut self,
408 value: &U,
409 ) -> Result<(), Self::Error> {
410 if !self.tag {
411 return value.serialize(&mut *self.encoder);
412 }
413
414 self.tag = false;
415 match value.serialize(crate::tag::Serializer) {
416 Ok(x) => Ok(self.encoder.0.push(Header::Tag(x))?),
417 _ => Err(Error::Value("expected tag".into())),
418 }
419 }
420
421 end!();
422 }
423
424 impl<'a, W: Write> ser::SerializeMap for CollectionSerializer<'a, W>
425 where
426 W::Error: core::fmt::Debug,
427 {
428 type Ok = ();
429 type Error = Error<W::Error>;
430
431 #[inline]
serialize_key<U: ?Sized + ser::Serialize>(&mut self, key: &U) -> Result<(), Self::Error>432 fn serialize_key<U: ?Sized + ser::Serialize>(&mut self, key: &U) -> Result<(), Self::Error> {
433 key.serialize(&mut *self.encoder)
434 }
435
436 #[inline]
serialize_value<U: ?Sized + ser::Serialize>( &mut self, value: &U, ) -> Result<(), Self::Error>437 fn serialize_value<U: ?Sized + ser::Serialize>(
438 &mut self,
439 value: &U,
440 ) -> Result<(), Self::Error> {
441 value.serialize(&mut *self.encoder)
442 }
443
444 end!();
445 }
446
447 impl<'a, W: Write> ser::SerializeStruct for CollectionSerializer<'a, W>
448 where
449 W::Error: core::fmt::Debug,
450 {
451 type Ok = ();
452 type Error = Error<W::Error>;
453
454 #[inline]
serialize_field<U: ?Sized + ser::Serialize>( &mut self, key: &'static str, value: &U, ) -> Result<(), Self::Error>455 fn serialize_field<U: ?Sized + ser::Serialize>(
456 &mut self,
457 key: &'static str,
458 value: &U,
459 ) -> Result<(), Self::Error> {
460 key.serialize(&mut *self.encoder)?;
461 value.serialize(&mut *self.encoder)?;
462 Ok(())
463 }
464
465 end!();
466 }
467
468 impl<'a, W: Write> ser::SerializeStructVariant for CollectionSerializer<'a, W>
469 where
470 W::Error: core::fmt::Debug,
471 {
472 type Ok = ();
473 type Error = Error<W::Error>;
474
475 #[inline]
serialize_field<U: ?Sized + ser::Serialize>( &mut self, key: &'static str, value: &U, ) -> Result<(), Self::Error>476 fn serialize_field<U: ?Sized + ser::Serialize>(
477 &mut self,
478 key: &'static str,
479 value: &U,
480 ) -> Result<(), Self::Error> {
481 key.serialize(&mut *self.encoder)?;
482 value.serialize(&mut *self.encoder)
483 }
484
485 end!();
486 }
487
488 /// Serializes as CBOR into a type with [`impl ciborium_io::Write`](ciborium_io::Write)
489 #[inline]
into_writer<T: ?Sized + ser::Serialize, W: Write>( value: &T, writer: W, ) -> Result<(), Error<W::Error>> where W::Error: core::fmt::Debug,490 pub fn into_writer<T: ?Sized + ser::Serialize, W: Write>(
491 value: &T,
492 writer: W,
493 ) -> Result<(), Error<W::Error>>
494 where
495 W::Error: core::fmt::Debug,
496 {
497 let mut encoder = Serializer::from(writer);
498 value.serialize(&mut encoder)
499 }
500