minicbor/
encode.rs

1//! Traits and types for encoding CBOR.
2//!
3//! This module defines the trait [`Encode`] and the actual [`Encoder`].
4//! It also defines a [`Write`] trait to store the encoded bytes.
5
6mod encoder;
7mod error;
8pub mod write;
9
10use crate::data::{IanaTag, Int, Tag, Tagged};
11
12pub use encoder::Encoder;
13pub use error::Error;
14pub use write::Write;
15
16/// A type that can be encoded to CBOR.
17///
18/// If this type's CBOR encoding is meant to be decoded by `Decode` impls
19/// derived with [`minicbor_derive`] *it is advisable to only produce a
20/// single CBOR data item*. Tagging, maps or arrays can and should be used
21/// for multiple values.
22pub trait Encode<C> {
23    /// Encode a value of this type using the given `Encoder`.
24    ///
25    /// In addition to the encoder a user provided encoding context is given
26    /// as another parameter. Most implementations of this trait do not need an
27    /// encoding context and should be completely generic in the context
28    /// type. In cases where a context is needed and the `Encode` impl type is
29    /// meant to be combined with other types that require a different context
30    /// type, it is preferrable to constrain the context type variable `C` with
31    /// a trait bound instead of fixing the type.
32    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>>;
33
34    /// Is this value of `Self` a nil value?
35    ///
36    /// This method is primarily used by `minicbor-derive`.
37    ///
38    /// Some types have a special value to denote the concept of "nothing", aka
39    /// nil. An example is the `Option` type with its `None` value. This
40    /// method--if overriden--allows checking if a value is such a special nil
41    /// value.
42    ///
43    /// NB: A type implementing `Encode` with an overriden `Encode::is_nil`
44    /// method should also override `Decode::nil` if it implements `Decode`
45    /// at all.
46    fn is_nil(&self) -> bool {
47        false
48    }
49}
50
51/// A type that can calculate its own CBOR encoding length.
52pub trait CborLen<C> {
53    /// Compute the CBOR encoding length in bytes of this value.
54    fn cbor_len(&self, ctx: &mut C) -> usize;
55}
56
57impl<C, T: Encode<C> + ?Sized> Encode<C> for &T {
58    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
59        (**self).encode(e, ctx)
60    }
61
62    fn is_nil(&self) -> bool {
63        (**self).is_nil()
64    }
65}
66
67impl<C, T: CborLen<C> + ?Sized> CborLen<C> for &T {
68    fn cbor_len(&self, ctx: &mut C) -> usize {
69        (**self).cbor_len(ctx)
70    }
71}
72
73impl<C, T: Encode<C> + ?Sized> Encode<C> for &mut T {
74    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
75        (**self).encode(e, ctx)
76    }
77
78    fn is_nil(&self) -> bool {
79        (**self).is_nil()
80    }
81}
82
83impl<C, T: CborLen<C> + ?Sized> CborLen<C> for &mut T {
84    fn cbor_len(&self, ctx: &mut C) -> usize {
85        (**self).cbor_len(ctx)
86    }
87}
88
89#[cfg(feature = "alloc")]
90impl<C, T: Encode<C> + ?Sized> Encode<C> for alloc::boxed::Box<T> {
91    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
92        (**self).encode(e, ctx)
93    }
94
95    fn is_nil(&self) -> bool {
96        (**self).is_nil()
97    }
98}
99
100#[cfg(feature = "alloc")]
101impl<C, T: CborLen<C> + ?Sized> CborLen<C> for alloc::boxed::Box<T> {
102    fn cbor_len(&self, ctx: &mut C) -> usize {
103        (**self).cbor_len(ctx)
104    }
105}
106
107impl<C> Encode<C> for str {
108    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
109        e.str(self)?.ok()
110    }
111}
112
113impl<C> CborLen<C> for str {
114    fn cbor_len(&self, ctx: &mut C) -> usize {
115        let n = self.len();
116        n.cbor_len(ctx) + n
117    }
118}
119
120impl<C, T: Encode<C>> Encode<C> for Option<T> {
121    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
122        if let Some(x) = self {
123            x.encode(e, ctx)?;
124        } else {
125            e.null()?;
126        }
127        Ok(())
128    }
129
130    fn is_nil(&self) -> bool {
131        self.is_none()
132    }
133}
134
135impl<C, T: CborLen<C>> CborLen<C> for Option<T> {
136    fn cbor_len(&self, ctx: &mut C) -> usize {
137        if let Some(x) = self {
138            x.cbor_len(ctx)
139        } else {
140            1
141        }
142    }
143}
144
145impl<C, T: Encode<C>, E: Encode<C>> Encode<C> for Result<T, E> {
146    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
147        e.array(2)?;
148        match self {
149            Ok(v)  => e.u32(0)?.encode_with(v, ctx)?.ok(),
150            Err(v) => e.u32(1)?.encode_with(v, ctx)?.ok()
151        }
152    }
153}
154
155impl<C, T: CborLen<C>, E: CborLen<C>> CborLen<C> for Result<T, E> {
156    fn cbor_len(&self, ctx: &mut C) -> usize {
157        1 + match self {
158            Ok(x)  => 1 + x.cbor_len(ctx),
159            Err(e) => 1 + e.cbor_len(ctx)
160        }
161    }
162}
163
164#[cfg(feature = "alloc")]
165impl<C> Encode<C> for alloc::string::String {
166    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
167        e.str(self)?.ok()
168    }
169}
170
171#[cfg(feature = "alloc")]
172impl<C> CborLen<C> for alloc::string::String {
173    fn cbor_len(&self, ctx: &mut C) -> usize {
174        let n = self.len();
175        n.cbor_len(ctx) + n
176    }
177}
178
179impl<C> Encode<C> for core::ffi::CStr {
180    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
181        e.bytes(self.to_bytes_with_nul())?.ok()
182    }
183}
184
185impl<C> CborLen<C> for core::ffi::CStr {
186    fn cbor_len(&self, ctx: &mut C) -> usize {
187        let n = self.to_bytes_with_nul().len();
188        n.cbor_len(ctx) + n
189    }
190}
191
192#[cfg(feature = "alloc")]
193impl<C> Encode<C> for alloc::ffi::CString {
194    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
195        self.as_c_str().encode(e, ctx)
196    }
197}
198
199#[cfg(feature = "alloc")]
200impl<C> CborLen<C> for alloc::ffi::CString {
201    fn cbor_len(&self, ctx: &mut C) -> usize {
202        self.as_c_str().cbor_len(ctx)
203    }
204}
205
206#[cfg(feature = "alloc")]
207impl<C, T> Encode<C> for alloc::borrow::Cow<'_, T>
208where
209    T: Encode<C> + alloc::borrow::ToOwned + ?Sized
210{
211    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
212        self.as_ref().encode(e, ctx)
213    }
214
215    fn is_nil(&self) -> bool {
216        self.as_ref().is_nil()
217    }
218}
219
220#[cfg(feature = "alloc")]
221impl<C, T> CborLen<C> for alloc::borrow::Cow<'_, T>
222where
223    T: CborLen<C> + alloc::borrow::ToOwned + ?Sized
224{
225    fn cbor_len(&self, ctx: &mut C) -> usize {
226        self.as_ref().cbor_len(ctx)
227    }
228}
229
230#[cfg(feature = "std")]
231impl<C, T, S> Encode<C> for std::collections::HashSet<T, S>
232where
233    T: Encode<C>,
234    S: std::hash::BuildHasher
235{
236    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
237        e.array(self.len() as u64)?;
238        for x in self {
239            x.encode(e, ctx)?
240        }
241        Ok(())
242    }
243}
244
245#[cfg(feature = "std")]
246impl<C, T, S> CborLen<C> for std::collections::HashSet<T, S>
247where
248    T: CborLen<C>,
249    S: std::hash::BuildHasher
250{
251    fn cbor_len(&self, ctx: &mut C) -> usize {
252        self.len().cbor_len(ctx) + self.iter().map(|x| x.cbor_len(ctx)).sum::<usize>()
253    }
254}
255
256#[cfg(feature = "std")]
257impl<C, K, V, S> Encode<C> for std::collections::HashMap<K, V, S>
258where
259    K: Encode<C> + Eq + std::hash::Hash,
260    V: Encode<C>,
261    S: std::hash::BuildHasher
262{
263    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
264        e.map(self.len() as u64)?;
265        for (k, v) in self {
266            k.encode(e, ctx)?;
267            v.encode(e, ctx)?;
268        }
269        Ok(())
270    }
271}
272
273#[cfg(feature = "std")]
274impl<C, K, V, S> CborLen<C> for std::collections::HashMap<K, V, S>
275where
276    K: CborLen<C>,
277    V: CborLen<C>,
278    S: std::hash::BuildHasher
279{
280    fn cbor_len(&self, ctx: &mut C) -> usize {
281        self.len().cbor_len(ctx) + self.iter()
282            .map(|(k, v)| k.cbor_len(ctx) + v.cbor_len(ctx))
283            .sum::<usize>()
284    }
285}
286
287#[cfg(feature = "alloc")]
288impl<C, K, V> Encode<C> for alloc::collections::BTreeMap<K, V>
289where
290    K: Encode<C> + Eq + Ord,
291    V: Encode<C>
292{
293    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
294        e.map(self.len() as u64)?;
295        for (k, v) in self {
296            k.encode(e, ctx)?;
297            v.encode(e, ctx)?;
298        }
299        Ok(())
300    }
301}
302
303#[cfg(feature = "alloc")]
304impl<C, K, V> CborLen<C> for alloc::collections::BTreeMap<K, V>
305where
306    K: CborLen<C>,
307    V: CborLen<C>,
308{
309    fn cbor_len(&self, ctx: &mut C) -> usize {
310        self.len().cbor_len(ctx) + self.iter()
311            .map(|(k, v)| k.cbor_len(ctx) + v.cbor_len(ctx))
312            .sum::<usize>()
313    }
314}
315
316impl<C, T> Encode<C> for core::marker::PhantomData<T> {
317    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
318        e.array(0)?.ok()
319    }
320}
321
322impl<C, T> CborLen<C> for core::marker::PhantomData<T> {
323    fn cbor_len(&self, _: &mut C) -> usize {
324        1
325    }
326}
327
328impl<C> Encode<C> for () {
329    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
330        e.array(0)?.ok()
331    }
332}
333
334impl<C> CborLen<C> for () {
335    fn cbor_len(&self, _: &mut C) -> usize {
336        1
337    }
338}
339
340impl<C, T: Encode<C>> Encode<C> for core::num::Wrapping<T> {
341    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
342        self.0.encode(e, ctx)
343    }
344}
345
346impl<C, T: CborLen<C>> CborLen<C> for core::num::Wrapping<T> {
347    fn cbor_len(&self, ctx: &mut C) -> usize {
348        self.0.cbor_len(ctx)
349    }
350}
351
352#[cfg(target_pointer_width = "16")]
353impl<C> Encode<C> for usize {
354    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
355        e.u16(*self as u16)?.ok()
356    }
357}
358
359#[cfg(target_pointer_width = "16")]
360impl<C> CborLen<C> for usize {
361    fn cbor_len(&self, ctx: &mut C) -> usize {
362        (*self as u16).cbor_len(ctx)
363    }
364}
365
366#[cfg(target_pointer_width = "32")]
367impl<C> Encode<C> for usize {
368    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
369        e.u32(*self as u32)?.ok()
370    }
371}
372
373#[cfg(target_pointer_width = "32")]
374impl<C> CborLen<C> for usize {
375    fn cbor_len(&self, ctx: &mut C) -> usize {
376        (*self as u32).cbor_len(ctx)
377    }
378}
379
380#[cfg(target_pointer_width = "64")]
381impl<C> Encode<C> for usize {
382    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
383        e.u64(*self as u64)?.ok()
384    }
385}
386
387#[cfg(target_pointer_width = "64")]
388impl<C> CborLen<C> for usize {
389    fn cbor_len(&self, ctx: &mut C) -> usize {
390        (*self as u64).cbor_len(ctx)
391    }
392}
393
394#[cfg(target_pointer_width = "16")]
395impl<C> Encode<C> for isize {
396    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
397        e.i16(*self as i16)?.ok()
398    }
399}
400
401#[cfg(target_pointer_width = "16")]
402impl<C> CborLen<C> for isize {
403    fn cbor_len(&self, ctx: &mut C) -> usize {
404        (*self as i16).cbor_len(ctx)
405    }
406}
407
408#[cfg(target_pointer_width = "32")]
409impl<C> Encode<C> for isize {
410    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
411        e.i32(*self as i32)?.ok()
412    }
413}
414
415#[cfg(target_pointer_width = "32")]
416impl<C> CborLen<C> for isize {
417    fn cbor_len(&self, ctx: &mut C) -> usize {
418        (*self as i32).cbor_len(ctx)
419    }
420}
421
422#[cfg(target_pointer_width = "64")]
423impl<C> Encode<C> for isize {
424    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
425        e.i64(*self as i64)?.ok()
426    }
427}
428
429#[cfg(target_pointer_width = "64")]
430impl<C> CborLen<C> for isize {
431    fn cbor_len(&self, ctx: &mut C) -> usize {
432        (*self as i64).cbor_len(ctx)
433    }
434}
435
436impl<C> Encode<C> for Int {
437    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
438        e.int(*self)?.ok()
439    }
440}
441
442impl<C> CborLen<C> for Int {
443    fn cbor_len(&self, ctx: &mut C) -> usize {
444        self.value().cbor_len(ctx)
445    }
446}
447
448impl<C> Encode<C> for Tag {
449    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
450        e.tag(*self)?.ok()
451    }
452}
453
454impl<C> CborLen<C> for Tag {
455    fn cbor_len(&self, ctx: &mut C) -> usize {
456        self.as_u64().cbor_len(ctx)
457    }
458}
459
460impl<C> Encode<C> for IanaTag {
461    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
462        e.tag(*self)?.ok()
463    }
464}
465
466impl<C> CborLen<C> for IanaTag {
467    fn cbor_len(&self, ctx: &mut C) -> usize {
468        self.tag().cbor_len(ctx)
469    }
470}
471
472impl<C, const N: u64, T: Encode<C>> Encode<C> for Tagged<N, T> {
473    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
474        e.tag(Tag::new(N))?.encode_with(self.value(), ctx)?.ok()
475    }
476}
477
478impl<C, const N: u64, T: CborLen<C>> CborLen<C> for Tagged<N, T> {
479    fn cbor_len(&self, ctx: &mut C) -> usize {
480        Tag::new(N).cbor_len(ctx) + self.value().cbor_len(ctx)
481    }
482}
483
484macro_rules! encode_basic {
485    ($($t:ident)*) => {
486        $(
487            impl<C> Encode<C> for $t {
488                fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
489                    e.$t(*self)?;
490                    Ok(())
491                }
492            }
493        )*
494    }
495}
496
497encode_basic!(u8 i8 u16 i16 u32 i32 u64 i64 bool f32 f64 char);
498
499impl<C> CborLen<C> for bool {
500    fn cbor_len(&self, _: &mut C) -> usize {
501        1
502    }
503}
504
505impl<C> CborLen<C> for char {
506    fn cbor_len(&self, ctx: &mut C) -> usize {
507        (*self as u32).cbor_len(ctx)
508    }
509}
510
511impl<C> CborLen<C> for u8 {
512    fn cbor_len(&self, _: &mut C) -> usize {
513        if let 0 ..= 0x17 = self { 1 } else { 2 }
514    }
515}
516
517impl<C> CborLen<C> for u16 {
518    fn cbor_len(&self, _: &mut C) -> usize {
519        match self {
520            0    ..= 0x17 => 1,
521            0x18 ..= 0xff => 2,
522            _             => 3
523        }
524    }
525}
526
527impl<C> CborLen<C> for u32 {
528    fn cbor_len(&self, _: &mut C) -> usize {
529        match self {
530            0     ..= 0x17   => 1,
531            0x18  ..= 0xff   => 2,
532            0x100 ..= 0xffff => 3,
533            _                => 5
534        }
535    }
536}
537
538impl<C> CborLen<C> for u64 {
539    fn cbor_len(&self, _: &mut C) -> usize {
540        match self {
541            0        ..= 0x17        => 1,
542            0x18     ..= 0xff        => 2,
543            0x100    ..= 0xffff      => 3,
544            0x1_0000 ..= 0xffff_ffff => 5,
545            _                        => 9
546        }
547    }
548}
549
550impl<C> CborLen<C> for i8 {
551    fn cbor_len(&self, ctx: &mut C) -> usize {
552        let x = if *self >= 0 { *self as u8 } else { (-1 - self) as u8 };
553        x.cbor_len(ctx)
554    }
555}
556
557impl<C> CborLen<C> for i16 {
558    fn cbor_len(&self, ctx: &mut C) -> usize {
559        let x = if *self >= 0 { *self as u16 } else { (-1 - self) as u16 };
560        x.cbor_len(ctx)
561    }
562}
563
564impl<C> CborLen<C> for i32 {
565    fn cbor_len(&self, ctx: &mut C) -> usize {
566        let x = if *self >= 0 { *self as u32 } else { (-1 - self) as u32 };
567        x.cbor_len(ctx)
568    }
569}
570
571impl<C> CborLen<C> for i64 {
572    fn cbor_len(&self, ctx: &mut C) -> usize {
573        let x = if *self >= 0 { *self as u64 } else { (-1 - self) as u64 };
574        x.cbor_len(ctx)
575    }
576}
577
578impl<C> CborLen<C> for f32 {
579    fn cbor_len(&self, _: &mut C) -> usize {
580        5
581    }
582}
583
584impl<C> CborLen<C> for f64 {
585    fn cbor_len(&self, _: &mut C) -> usize {
586        9
587    }
588}
589
590macro_rules! encode_nonzero {
591    ($($t:ty)*) => {
592        $(
593            impl<C> Encode<C> for $t {
594                fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
595                    self.get().encode(e, ctx)
596                }
597            }
598
599            impl<C> CborLen<C> for $t {
600                fn cbor_len(&self, ctx: &mut C) -> usize {
601                    self.get().cbor_len(ctx)
602                }
603            }
604        )*
605    }
606}
607
608encode_nonzero! {
609    core::num::NonZeroU8
610    core::num::NonZeroU16
611    core::num::NonZeroU32
612    core::num::NonZeroU64
613    core::num::NonZeroI8
614    core::num::NonZeroI16
615    core::num::NonZeroI32
616    core::num::NonZeroI64
617}
618
619#[cfg(any(target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64"))]
620encode_nonzero! {
621    core::num::NonZeroUsize
622    core::num::NonZeroIsize
623}
624
625#[cfg(any(
626    target_has_atomic = "8",
627    target_has_atomic = "16",
628    target_has_atomic = "32",
629    target_has_atomic = "64",
630    target_has_atomic = "ptr",
631))]
632macro_rules! encode_atomic {
633    ($($t:ty)*) => {
634        $(
635            impl<C> Encode<C> for $t {
636                fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
637                    self.load(core::sync::atomic::Ordering::SeqCst).encode(e, ctx)?;
638                    Ok(())
639                }
640            }
641
642            impl<C> CborLen<C> for $t {
643                fn cbor_len(&self, ctx: &mut C) -> usize {
644                    self.load(core::sync::atomic::Ordering::SeqCst).cbor_len(ctx)
645                }
646            }
647        )*
648    }
649}
650
651#[cfg(target_has_atomic = "8")]
652encode_atomic! {
653    core::sync::atomic::AtomicBool
654    core::sync::atomic::AtomicU8
655    core::sync::atomic::AtomicI8
656}
657
658#[cfg(target_has_atomic = "16")]
659encode_atomic! {
660    core::sync::atomic::AtomicU16
661    core::sync::atomic::AtomicI16
662}
663
664#[cfg(target_has_atomic = "32")]
665encode_atomic! {
666    core::sync::atomic::AtomicU32
667    core::sync::atomic::AtomicI32
668}
669
670#[cfg(target_has_atomic = "64")]
671encode_atomic! {
672    core::sync::atomic::AtomicU64
673    core::sync::atomic::AtomicI64
674}
675
676#[cfg(target_has_atomic = "ptr")]
677encode_atomic! {
678    core::sync::atomic::AtomicUsize
679    core::sync::atomic::AtomicIsize
680}
681
682macro_rules! encode_sequential {
683    ($($t:ty)*) => {
684        $(
685            impl<C, T: Encode<C>> Encode<C> for $t {
686                fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
687                    e.array(self.len() as u64)?;
688                    for x in self {
689                        x.encode(e, ctx)?
690                    }
691                    Ok(())
692                }
693            }
694
695            impl<C, T: CborLen<C>> CborLen<C> for $t {
696                fn cbor_len(&self, ctx: &mut C) -> usize {
697                    let n = self.len();
698                    n.cbor_len(ctx) + self.iter().map(|x| x.cbor_len(ctx)).sum::<usize>()
699                }
700            }
701        )*
702    }
703}
704
705encode_sequential!([T]);
706
707#[cfg(feature = "alloc")]
708encode_sequential! {
709    alloc::vec::Vec<T>
710    alloc::collections::VecDeque<T>
711    alloc::collections::LinkedList<T>
712    alloc::collections::BinaryHeap<T>
713    alloc::collections::BTreeSet<T>
714}
715
716impl <C, T: Encode<C>, const N: usize> Encode<C> for [T; N] {
717    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
718        e.array(N as u64)?;
719        for x in self {
720            x.encode(e, ctx)?
721        }
722        Ok(())
723    }
724}
725
726impl<C, T: CborLen<C>, const N: usize> CborLen<C> for [T; N] {
727    fn cbor_len(&self, ctx: &mut C) -> usize {
728        N.cbor_len(ctx) + self.iter().map(|x| x.cbor_len(ctx)).sum::<usize>()
729    }
730}
731
732macro_rules! encode_tuples {
733    ($( $len:expr => { $($T:ident ($idx:tt))+ } )+) => {
734        $(
735            impl<Ctx, $($T: Encode<Ctx>),+> Encode<Ctx> for ($($T,)+) {
736                fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut Ctx) -> Result<(), Error<W::Error>> {
737                    e.array($len)?
738                        $(.encode_with(&self.$idx, ctx)?)+
739                        .ok()
740                }
741            }
742
743            impl<Ctx, $($T: CborLen<Ctx>),+> CborLen<Ctx> for ($($T,)+) {
744                fn cbor_len(&self, ctx: &mut Ctx) -> usize {
745                    $len.cbor_len(ctx) $(+ self.$idx.cbor_len(ctx))+
746                }
747            }
748        )+
749    }
750}
751
752encode_tuples! {
753    1  => { A(0) }
754    2  => { A(0) B(1) }
755    3  => { A(0) B(1) C(2) }
756    4  => { A(0) B(1) C(2) D(3) }
757    5  => { A(0) B(1) C(2) D(3) E(4) }
758    6  => { A(0) B(1) C(2) D(3) E(4) F(5) }
759    7  => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) }
760    8  => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) }
761    9  => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) }
762    10 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) }
763    11 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) K(10) }
764    12 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) K(10) L(11) }
765    13 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) K(10) L(11) M(12) }
766    14 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) K(10) L(11) M(12) N(13) }
767    15 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) K(10) L(11) M(12) N(13) O(14) }
768    16 => { A(0) B(1) C(2) D(3) E(4) F(5) G(6) H(7) I(8) J(9) K(10) L(11) M(12) N(13) O(14) P(15) }
769}
770
771impl<C> Encode<C> for core::time::Duration {
772    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
773        e.array(2)?
774            .encode_with(self.as_secs(), ctx)?
775            .encode_with(self.subsec_nanos(), ctx)?
776            .ok()
777    }
778}
779
780impl<C> CborLen<C> for core::time::Duration {
781    fn cbor_len(&self, ctx: &mut C) -> usize {
782        1 + self.as_secs().cbor_len(ctx) + self.subsec_nanos().cbor_len(ctx)
783    }
784}
785
786#[cfg(feature = "std")]
787impl<C> Encode<C> for std::time::SystemTime {
788    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
789        match self.duration_since(std::time::UNIX_EPOCH) {
790            Ok(d)  => d.encode(e, ctx),
791            Err(e) => Err(Error::custom(e).with_message("when encoding system time"))
792        }
793    }
794}
795
796#[cfg(feature = "std")]
797impl<C> CborLen<C> for std::time::SystemTime{
798    fn cbor_len(&self, ctx: &mut C) -> usize {
799        self.duration_since(std::time::UNIX_EPOCH)
800            .map(|d| d.cbor_len(ctx))
801            .unwrap_or(0)
802    }
803}
804
805impl<C, T: Encode<C> + Copy> Encode<C> for core::cell::Cell<T> {
806    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
807        self.get().encode(e, ctx)
808    }
809
810    fn is_nil(&self) -> bool {
811        self.get().is_nil()
812    }
813}
814
815impl<C, T: CborLen<C> + Copy> CborLen<C> for core::cell::Cell<T> {
816    fn cbor_len(&self, ctx: &mut C) -> usize {
817        self.get().cbor_len(ctx)
818    }
819}
820
821impl<C, T: Encode<C>> Encode<C> for core::cell::RefCell<T> {
822    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
823        self.borrow().encode(e, ctx)
824    }
825
826    fn is_nil(&self) -> bool {
827        self.borrow().is_nil()
828    }
829}
830
831impl<C, T: CborLen<C>> CborLen<C> for core::cell::RefCell<T> {
832    fn cbor_len(&self, ctx: &mut C) -> usize {
833        self.borrow().cbor_len(ctx)
834    }
835}
836
837#[cfg(feature = "std")]
838impl<C> Encode<C> for std::path::Path {
839    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
840        if let Some(s) = self.to_str() {
841            e.str(s)?.ok()
842        } else {
843            Err(Error::message("non-utf-8 path values are not supported"))
844        }
845    }
846}
847
848#[cfg(feature = "std")]
849impl<C> CborLen<C> for std::path::Path {
850    fn cbor_len(&self, ctx: &mut C) -> usize {
851        self.to_str().map(|s| s.cbor_len(ctx)).unwrap_or(0)
852    }
853}
854
855#[cfg(feature = "std")]
856impl<C> Encode<C> for std::path::PathBuf {
857    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
858        self.as_path().encode(e, ctx)
859    }
860}
861
862#[cfg(feature = "std")]
863impl<C> CborLen<C> for std::path::PathBuf {
864    fn cbor_len(&self, ctx: &mut C) -> usize {
865        self.as_path().cbor_len(ctx)
866    }
867}
868
869#[cfg(feature = "std")]
870impl<C> Encode<C> for std::net::IpAddr {
871    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
872        e.array(2)?;
873        match self {
874            std::net::IpAddr::V4(a) => e.u32(0)?.encode_with(a, ctx)?.ok(),
875            std::net::IpAddr::V6(a) => e.u32(1)?.encode_with(a, ctx)?.ok()
876        }
877    }
878}
879
880#[cfg(feature = "std")]
881impl<C> CborLen<C> for std::net::IpAddr {
882    fn cbor_len(&self, ctx: &mut C) -> usize {
883        1 + match self {
884            std::net::IpAddr::V4(a) => 1 + a.cbor_len(ctx),
885            std::net::IpAddr::V6(a) => 1 + a.cbor_len(ctx),
886        }
887    }
888}
889
890#[cfg(feature = "std")]
891impl<C> Encode<C> for std::net::Ipv4Addr {
892    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
893        e.bytes(&self.octets())?.ok()
894    }
895}
896
897#[cfg(feature = "std")]
898impl<C> CborLen<C> for std::net::Ipv4Addr {
899    fn cbor_len(&self, _: &mut C) -> usize {
900        5
901    }
902}
903
904#[cfg(feature = "std")]
905impl<C> Encode<C> for std::net::Ipv6Addr {
906    fn encode<W: Write>(&self, e: &mut Encoder<W>, _: &mut C) -> Result<(), Error<W::Error>> {
907        e.bytes(&self.octets())?.ok()
908    }
909}
910
911#[cfg(feature = "std")]
912impl<C> CborLen<C> for std::net::Ipv6Addr {
913    fn cbor_len(&self, _: &mut C) -> usize {
914        17
915    }
916}
917
918#[cfg(feature = "std")]
919impl<C> Encode<C> for std::net::SocketAddr {
920    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
921        e.array(2)?;
922        match self {
923            std::net::SocketAddr::V4(a) => e.u32(0)?.encode_with(a, ctx)?.ok(),
924            std::net::SocketAddr::V6(a) => e.u32(1)?.encode_with(a, ctx)?.ok()
925        }
926    }
927}
928
929#[cfg(feature = "std")]
930impl<C> CborLen<C> for std::net::SocketAddr {
931    fn cbor_len(&self, ctx: &mut C) -> usize {
932        1 + match self {
933            std::net::SocketAddr::V4(a) => 1 + a.cbor_len(ctx),
934            std::net::SocketAddr::V6(a) => 1 + a.cbor_len(ctx),
935        }
936    }
937}
938
939#[cfg(feature = "std")]
940impl<C> Encode<C> for std::net::SocketAddrV4 {
941    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
942        e.array(2)?
943            .encode_with(self.ip(), ctx)?
944            .encode_with(self.port(), ctx)?
945            .ok()
946    }
947}
948
949#[cfg(feature = "std")]
950impl<C> CborLen<C> for std::net::SocketAddrV4 {
951    fn cbor_len(&self, ctx: &mut C) -> usize {
952        1 + self.ip().cbor_len(ctx) + self.port().cbor_len(ctx)
953    }
954}
955
956#[cfg(feature = "std")]
957impl<C> Encode<C> for std::net::SocketAddrV6 {
958    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
959        e.array(2)?
960            .encode_with(self.ip(), ctx)?
961            .encode_with(self.port(), ctx)?
962            .ok()
963    }
964}
965
966#[cfg(feature = "std")]
967impl<C> CborLen<C> for std::net::SocketAddrV6 {
968    fn cbor_len(&self, ctx: &mut C) -> usize {
969        1 + self.ip().cbor_len(ctx) + self.port().cbor_len(ctx)
970    }
971}
972
973impl<C, T: Encode<C>> Encode<C> for core::ops::Range<T> {
974    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
975        e.array(2)?
976            .encode_with(&self.start, ctx)?
977            .encode_with(&self.end, ctx)?
978            .ok()
979    }
980}
981
982impl<C, T: CborLen<C>> CborLen<C> for core::ops::Range<T> {
983    fn cbor_len(&self, ctx: &mut C) -> usize {
984        1 + self.start.cbor_len(ctx) + self.end.cbor_len(ctx)
985    }
986}
987
988impl<C, T: Encode<C>> Encode<C> for core::ops::RangeFrom<T> {
989    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
990        e.array(1)?
991            .encode_with(&self.start, ctx)?
992            .ok()
993    }
994}
995
996impl<C, T: CborLen<C>> CborLen<C> for core::ops::RangeFrom<T> {
997    fn cbor_len(&self, ctx: &mut C) -> usize {
998        1 + self.start.cbor_len(ctx)
999    }
1000}
1001
1002impl<C, T: Encode<C>> Encode<C> for core::ops::RangeTo<T> {
1003    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
1004        e.array(1)?
1005            .encode_with(&self.end, ctx)?
1006            .ok()
1007    }
1008}
1009
1010impl<C, T: CborLen<C>> CborLen<C> for core::ops::RangeTo<T> {
1011    fn cbor_len(&self, ctx: &mut C) -> usize {
1012        1 + self.end.cbor_len(ctx)
1013    }
1014}
1015
1016impl<C, T: Encode<C>> Encode<C> for core::ops::RangeToInclusive<T> {
1017    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
1018        e.array(1)?
1019            .encode_with(&self.end, ctx)?
1020            .ok()
1021    }
1022}
1023
1024impl<C, T: CborLen<C>> CborLen<C> for core::ops::RangeToInclusive<T> {
1025    fn cbor_len(&self, ctx: &mut C) -> usize {
1026        1 + self.end.cbor_len(ctx)
1027    }
1028}
1029
1030impl<C, T: Encode<C>> Encode<C> for core::ops::RangeInclusive<T> {
1031    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
1032        e.array(2)?
1033            .encode_with(self.start(), ctx)?
1034            .encode_with(self.end(), ctx)?
1035            .ok()
1036    }
1037}
1038
1039impl<C, T: CborLen<C>> CborLen<C> for core::ops::RangeInclusive<T> {
1040    fn cbor_len(&self, ctx: &mut C) -> usize {
1041        1 + self.start().cbor_len(ctx) + self.end().cbor_len(ctx)
1042    }
1043}
1044
1045impl<C, T: Encode<C>> Encode<C> for core::ops::Bound<T> {
1046    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
1047        e.array(2)?;
1048        match self {
1049            core::ops::Bound::Included(v) => e.u32(0)?.encode_with(v, ctx)?.ok(),
1050            core::ops::Bound::Excluded(v) => e.u32(1)?.encode_with(v, ctx)?.ok(),
1051            core::ops::Bound::Unbounded   => e.u32(2)?.array(0)?.ok()
1052        }
1053    }
1054}
1055
1056impl<C, T: CborLen<C>> CborLen<C> for core::ops::Bound<T> {
1057    fn cbor_len(&self, ctx: &mut C) -> usize {
1058        1 + match self {
1059            core::ops::Bound::Included(v) => 1 + v.cbor_len(ctx),
1060            core::ops::Bound::Excluded(v) => 1 + v.cbor_len(ctx),
1061            core::ops::Bound::Unbounded   => 2
1062        }
1063    }
1064}
1065
1066/// An encodable iterator writing its items as a CBOR array.
1067///
1068/// This type wraps any type implementing [`Iterator`] + [`Clone`] and encodes
1069/// the items produced by the iterator as a CBOR array.
1070#[derive(Debug)]
1071pub struct ArrayIter<I>(I);
1072
1073impl<I> ArrayIter<I> {
1074    pub fn new(it: I) -> Self {
1075        ArrayIter(it)
1076    }
1077}
1078
1079impl<C, I, T> Encode<C> for ArrayIter<I>
1080where
1081    I: Iterator<Item = T> + Clone,
1082    T: Encode<C>
1083{
1084    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
1085        let iter = self.0.clone();
1086        let (low, up) = iter.size_hint();
1087        let exact = Some(low) == up;
1088        if exact {
1089            e.array(low as u64)?;
1090        } else {
1091            e.begin_array()?;
1092        }
1093        for item in iter {
1094            item.encode(e, ctx)?;
1095        }
1096        if !exact {
1097            e.end()?;
1098        }
1099        Ok(())
1100    }
1101}
1102
1103/// An encodable iterator writing its items as a CBOR map.
1104///
1105/// This type wraps any type implementing [`Iterator`] + [`Clone`] and encodes
1106/// the items produced by the iterator as a CBOR map.
1107#[derive(Debug)]
1108pub struct MapIter<I>(I);
1109
1110impl<I> MapIter<I> {
1111    pub fn new(it: I) -> Self {
1112        MapIter(it)
1113    }
1114}
1115
1116impl<C, I, K, V> Encode<C> for MapIter<I>
1117where
1118    I: Iterator<Item = (K, V)> + Clone,
1119    K: Encode<C>,
1120    V: Encode<C>
1121{
1122    fn encode<W: Write>(&self, e: &mut Encoder<W>, ctx: &mut C) -> Result<(), Error<W::Error>> {
1123        let iter = self.0.clone();
1124        let (low, up) = iter.size_hint();
1125        let exact = Some(low) == up;
1126        if exact {
1127            e.map(low as u64)?;
1128        } else {
1129            e.begin_map()?;
1130        }
1131        for (k, v) in iter {
1132            k.encode(e, ctx)?;
1133            v.encode(e, ctx)?;
1134        }
1135        if !exact {
1136            e.end()?;
1137        }
1138        Ok(())
1139    }
1140}