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