1// SPDX-License-Identifier: Apache-2.0
2
3//! Serde serialization support for CBOR
4
5mod error;
6
7pub use error::Error;
8
9use alloc::string::ToString;
10
11use ciborium_io::Write;
12use ciborium_ll::*;
13use serde::{ser, Serialize as _};
14
15struct Serializer<W: Write>(Encoder<W>);
16
17impl<W: Write> From<W> for Serializer<W> {
18 #[inline]
19 fn from(writer: W) -> Self {
20 Self(writer.into())
21 }
22}
23
24impl<W: Write> From<Encoder<W>> for Serializer<W> {
25 #[inline]
26 fn from(writer: Encoder<W>) -> Self {
27 Self(writer)
28 }
29}
30
31impl<'a, W: Write> ser::Serializer for &'a mut Serializer<W>
32where
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]
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]
55 fn serialize_i8(self, v: i8) -> Result<(), Self::Error> {
56 self.serialize_i64(v.into())
57 }
58
59 #[inline]
60 fn serialize_i16(self, v: i16) -> Result<(), Self::Error> {
61 self.serialize_i64(v.into())
62 }
63
64 #[inline]
65 fn serialize_i32(self, v: i32) -> Result<(), Self::Error> {
66 self.serialize_i64(v.into())
67 }
68
69 #[inline]
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]
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]
104 fn serialize_u8(self, v: u8) -> Result<(), Self::Error> {
105 self.serialize_u64(v.into())
106 }
107
108 #[inline]
109 fn serialize_u16(self, v: u16) -> Result<(), Self::Error> {
110 self.serialize_u64(v.into())
111 }
112
113 #[inline]
114 fn serialize_u32(self, v: u32) -> Result<(), Self::Error> {
115 self.serialize_u64(v.into())
116 }
117
118 #[inline]
119 fn serialize_u64(self, v: u64) -> Result<(), Self::Error> {
120 Ok(self.0.push(Header::Positive(v))?)
121 }
122
123 #[inline]
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]
143 fn serialize_f32(self, v: f32) -> Result<(), Self::Error> {
144 self.serialize_f64(v.into())
145 }
146
147 #[inline]
148 fn serialize_f64(self, v: f64) -> Result<(), Self::Error> {
149 Ok(self.0.push(Header::Float(v))?)
150 }
151
152 #[inline]
153 fn serialize_char(self, v: char) -> Result<(), Self::Error> {
154 self.serialize_str(&v.to_string())
155 }
156
157 #[inline]
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]
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]
171 fn serialize_none(self) -> Result<(), Self::Error> {
172 Ok(self.0.push(Header::Simple(simple::NULL))?)
173 }
174
175 #[inline]
176 fn serialize_some<U: ?Sized + ser::Serialize>(self, value: &U) -> Result<(), Self::Error> {
177 value.serialize(self)
178 }
179
180 #[inline]
181 fn serialize_unit(self) -> Result<(), Self::Error> {
182 self.serialize_none()
183 }
184
185 #[inline]
186 fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> {
187 self.serialize_unit()
188 }
189
190 #[inline]
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]
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]
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]
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]
236 fn serialize_tuple(self, length: usize) -> Result<Self::SerializeTuple, Self::Error> {
237 self.serialize_seq(Some(length))
238 }
239
240 #[inline]
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]
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]
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]
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]
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]
320 fn is_human_readable(&self) -> bool {
321 false
322 }
323}
324
325macro_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
338struct CollectionSerializer<'a, W: Write> {
339 encoder: &'a mut Serializer<W>,
340 ending: bool,
341 tag: bool,
342}
343
344impl<'a, W: Write> ser::SerializeSeq for CollectionSerializer<'a, W>
345where
346 W::Error: core::fmt::Debug,
347{
348 type Ok = ();
349 type Error = Error<W::Error>;
350
351 #[inline]
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
362impl<'a, W: Write> ser::SerializeTuple for CollectionSerializer<'a, W>
363where
364 W::Error: core::fmt::Debug,
365{
366 type Ok = ();
367 type Error = Error<W::Error>;
368
369 #[inline]
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
380impl<'a, W: Write> ser::SerializeTupleStruct for CollectionSerializer<'a, W>
381where
382 W::Error: core::fmt::Debug,
383{
384 type Ok = ();
385 type Error = Error<W::Error>;
386
387 #[inline]
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
398impl<'a, W: Write> ser::SerializeTupleVariant for CollectionSerializer<'a, W>
399where
400 W::Error: core::fmt::Debug,
401{
402 type Ok = ();
403 type Error = Error<W::Error>;
404
405 #[inline]
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
424impl<'a, W: Write> ser::SerializeMap for CollectionSerializer<'a, W>
425where
426 W::Error: core::fmt::Debug,
427{
428 type Ok = ();
429 type Error = Error<W::Error>;
430
431 #[inline]
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]
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
447impl<'a, W: Write> ser::SerializeStruct for CollectionSerializer<'a, W>
448where
449 W::Error: core::fmt::Debug,
450{
451 type Ok = ();
452 type Error = Error<W::Error>;
453
454 #[inline]
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
468impl<'a, W: Write> ser::SerializeStructVariant for CollectionSerializer<'a, W>
469where
470 W::Error: core::fmt::Debug,
471{
472 type Ok = ();
473 type Error = Error<W::Error>;
474
475 #[inline]
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]
490pub fn into_writer<T: ?Sized + ser::Serialize, W: Write>(
491 value: &T,
492 writer: W,
493) -> Result<(), Error<W::Error>>
494where
495 W::Error: core::fmt::Debug,
496{
497 let mut encoder = Serializer::from(writer);
498 value.serialize(&mut encoder)
499}
500