minicbor/
decode.rs

1//! Traits and types for decoding CBOR.
2//!
3//! This module defines the trait [`Decode`] and the actual [`Decoder`].
4
5use core::mem::MaybeUninit;
6
7mod decoder;
8mod error;
9pub mod info;
10
11use crate::data::{Int, Tag, Tagged};
12
13pub use decoder::{Decoder, Probe};
14pub use decoder::{ArrayIter, ArrayIterWithCtx, BytesIter, MapIter, MapIterWithCtx, StrIter};
15pub use error::Error;
16
17#[cfg(feature = "half")]
18mod tokenizer;
19
20#[cfg(feature = "half")]
21pub use tokenizer::Tokenizer;
22
23#[cfg(feature = "half")]
24#[deprecated(since = "0.23.0", note = "import `Token` from `minicbor::data` instead")]
25pub type Token<'b> = crate::data::Token<'b>;
26
27/// A type that can be decoded from CBOR.
28pub trait Decode<'b, C>: Sized {
29    /// Decode a value using the given `Decoder`.
30    ///
31    /// In addition to the decoder a user provided decoding context is given
32    /// as another parameter. Most implementations of this trait do not need
33    /// a decoding context and should be completely generic in the context
34    /// type. In cases where a context is needed and the `Decode` impl type is
35    /// meant to be combined with other types that require a different context
36    /// type, it is preferrable to constrain the context type variable `C` with
37    /// a trait bound instead of fixing the type.
38    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error>;
39
40    /// If possible, return a nil value of `Self`.
41    ///
42    /// This method is primarily used by `minicbor-derive` and allows
43    /// creating a special value denoting the absence of a "real" value if
44    /// no CBOR value is present. The canonical example of a type where
45    /// this is sensible is the `Option` type, whose `Decode::nil` method
46    /// would return `Some(None)`.
47    ///
48    /// With the exception of `Option<_>` all types `T` are considered
49    /// mandatory by default, i.e. `T::nil()` returns `None`. Missing values
50    /// of `T` therefore cause decoding errors in derived `Decode`
51    /// implementations.
52    ///
53    /// NB: A type implementing `Decode` with an overriden `Decode::nil`
54    /// method should also override `Encode::is_nil` if it implements `Encode`
55    /// at all.
56    fn nil() -> Option<Self> {
57        None
58    }
59}
60
61#[cfg(feature = "alloc")]
62impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for alloc::boxed::Box<T> {
63    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
64        T::decode(d, ctx).map(alloc::boxed::Box::new)
65    }
66}
67
68impl<'a, 'b: 'a, C> Decode<'b, C> for &'a str {
69    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
70        d.str()
71    }
72}
73
74#[cfg(feature = "alloc")]
75impl<'b, C, T> Decode<'b, C> for alloc::borrow::Cow<'_, T>
76where
77    T: alloc::borrow::ToOwned + ?Sized,
78    T::Owned: Decode<'b, C>
79{
80    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
81        d.decode_with(ctx).map(alloc::borrow::Cow::Owned)
82    }
83}
84
85#[cfg(feature = "alloc")]
86impl<'b, C> Decode<'b, C> for alloc::string::String {
87    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
88        d.str().map(alloc::string::String::from)
89    }
90}
91
92impl<'a, 'b: 'a, C> Decode<'b, C> for &'a core::ffi::CStr {
93    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
94        let p = d.position();
95        let b = d.bytes()?;
96        core::ffi::CStr::from_bytes_with_nul(b).map_err(|_| Error::message("invalid c-string").at(p))
97    }
98}
99
100#[cfg(feature = "alloc")]
101impl<'b, C> Decode<'b, C> for alloc::ffi::CString {
102    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
103        let c: &core::ffi::CStr = d.decode()?;
104        Ok(Self::from(c))
105    }
106}
107
108#[cfg(feature = "alloc")]
109impl<'b, C> Decode<'b, C> for alloc::boxed::Box<str> {
110    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
111        d.str().map(Into::into)
112    }
113}
114
115impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for Option<T> {
116    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
117        if crate::data::Type::Null == d.datatype()? {
118            d.skip()?;
119            return Ok(None)
120        }
121        T::decode(d, ctx).map(Some)
122    }
123
124    fn nil() -> Option<Self> {
125        Some(None)
126    }
127}
128
129impl<'b, C, T, E> Decode<'b, C> for Result<T, E>
130where
131    T: Decode<'b, C>,
132    E: Decode<'b, C>
133{
134    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
135        let p = d.position();
136        if Some(2) != d.array()? {
137            return Err(Error::message("expected enum (2-element array)").at(p))
138        }
139        let p = d.position();
140        match d.i64()? {
141            0 => T::decode(d, ctx).map(Ok),
142            1 => E::decode(d, ctx).map(Err),
143            n => Err(Error::unknown_variant(n).at(p))
144        }
145    }
146}
147
148#[cfg(feature = "alloc")]
149impl<'b, C, T> Decode<'b, C> for alloc::collections::BinaryHeap<T>
150where
151    T: Decode<'b, C> + Ord
152{
153    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
154        let iter: ArrayIterWithCtx<C, T> = d.array_iter_with(ctx)?;
155        let mut v = alloc::collections::BinaryHeap::new();
156        for x in iter {
157            v.push(x?)
158        }
159        Ok(v)
160    }
161}
162
163#[cfg(feature = "std")]
164impl<'b, C, T, S> Decode<'b, C> for std::collections::HashSet<T, S>
165where
166    T: Decode<'b, C> + Eq + std::hash::Hash,
167    S: std::hash::BuildHasher + std::default::Default
168{
169    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
170        let iter: ArrayIterWithCtx<C, T> = d.array_iter_with(ctx)?;
171        let mut v = std::collections::HashSet::default();
172        for x in iter {
173            v.insert(x?);
174        }
175        Ok(v)
176    }
177}
178
179#[cfg(feature = "alloc")]
180impl<'b, C, T> Decode<'b, C> for alloc::collections::BTreeSet<T>
181where
182    T: Decode<'b, C> + Ord
183{
184    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
185        let iter: ArrayIterWithCtx<C, T> = d.array_iter_with(ctx)?;
186        let mut v = alloc::collections::BTreeSet::new();
187        for x in iter {
188            v.insert(x?);
189        }
190        Ok(v)
191    }
192}
193
194#[cfg(feature = "std")]
195impl<'b, C, K, V, S> Decode<'b, C> for std::collections::HashMap<K, V, S>
196where
197    K: Decode<'b, C> + Eq + std::hash::Hash,
198    V: Decode<'b, C>,
199    S: std::hash::BuildHasher + std::default::Default
200{
201    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
202        let mut m = std::collections::HashMap::default();
203        let iter: MapIterWithCtx<C, K, V> = d.map_iter_with(ctx)?;
204        for x in iter {
205            let (k, v) = x?;
206            m.insert(k, v);
207        }
208        Ok(m)
209    }
210}
211
212#[cfg(feature = "alloc")]
213impl<'b, C, K, V> Decode<'b, C> for alloc::collections::BTreeMap<K, V>
214where
215    K: Decode<'b, C> + Eq + Ord,
216    V: Decode<'b, C>
217{
218    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
219        let mut m = alloc::collections::BTreeMap::new();
220        let iter: MapIterWithCtx<C, K, V> = d.map_iter_with(ctx)?;
221        for x in iter {
222            let (k, v) = x?;
223            m.insert(k, v);
224        }
225        Ok(m)
226    }
227}
228
229impl<'b, C, T> Decode<'b, C> for core::marker::PhantomData<T> {
230    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
231        let p = d.position();
232        if Some(0) != d.array()? {
233            return Err(Error::message("expected phantom data, i.e. an empty array").at(p))
234        }
235        Ok(core::marker::PhantomData)
236    }
237}
238
239impl<'b, C> Decode<'b, C> for () {
240    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
241        let p = d.position();
242        if Some(0) != d.array()? {
243            return Err(Error::message("expected unit, i.e. an empty array").at(p))
244        }
245        Ok(())
246    }
247}
248
249impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::num::Wrapping<T> {
250    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
251        d.decode_with(ctx).map(core::num::Wrapping)
252    }
253}
254
255#[cfg(target_pointer_width = "16")]
256impl<'b, C> Decode<'b, C> for usize {
257    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
258        d.u16().map(|n| n as usize)
259    }
260}
261
262#[cfg(target_pointer_width = "32")]
263impl<'b, C> Decode<'b, C> for usize {
264    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
265        d.u32().map(|n| n as usize)
266    }
267}
268
269#[cfg(target_pointer_width = "64")]
270impl<'b, C> Decode<'b, C> for usize {
271    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
272        d.u64().map(|n| n as usize)
273    }
274}
275
276#[cfg(target_pointer_width = "16")]
277impl<'b, C> Decode<'b, C> for isize {
278    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
279        d.i16().map(|n| n as isize)
280    }
281}
282
283#[cfg(target_pointer_width = "32")]
284impl<'b, C> Decode<'b, C> for isize {
285    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
286        d.i32().map(|n| n as isize)
287    }
288}
289
290#[cfg(target_pointer_width = "64")]
291impl<'b, C> Decode<'b, C> for isize {
292    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
293        d.i64().map(|n| n as isize)
294    }
295}
296
297impl<'b, C> Decode<'b, C> for Int {
298    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
299        d.int()
300    }
301}
302
303impl<'b, C> Decode<'b, C> for Tag {
304    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
305        d.tag()
306    }
307}
308
309impl<'b, C, const N: u64, T: Decode<'b, C>> Decode<'b, C> for Tagged<N, T> {
310    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
311        let p = d.position();
312        let t = d.tag()?;
313        if N != t.as_u64() {
314            #[cfg(feature = "alloc")]
315            return Err(Error::tag_mismatch(t).with_message(alloc::format!("expected tag {N}")).at(p));
316            #[cfg(not(feature = "alloc"))]
317            return Err(Error::tag_mismatch(t).at(p))
318        }
319        let v = d.decode_with(ctx)?;
320        Ok(Tagged::new(v))
321    }
322}
323
324macro_rules! decode_basic {
325    ($($t:ident)*) => {
326        $(
327            impl<'b, C> Decode<'b, C> for $t {
328                fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
329                    d.$t()
330                }
331            }
332        )*
333    }
334}
335
336decode_basic!(u8 i8 u16 i16 u32 i32 u64 i64 bool f32 f64 char);
337
338macro_rules! decode_nonzero {
339    ($($t:ty, $msg:expr)*) => {
340        $(
341            impl<'b, C> Decode<'b, C> for $t {
342                fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
343                    let p = d.position();
344                    <$t>::new(Decode::decode(d, ctx)?).ok_or_else(|| Error::message($msg).at(p))
345                }
346            }
347        )*
348    }
349}
350
351decode_nonzero! {
352    core::num::NonZeroU8,  "unexpected 0 when decoding a `NonZeroU8`"
353    core::num::NonZeroU16, "unexpected 0 when decoding a `NonZeroU16`"
354    core::num::NonZeroU32, "unexpected 0 when decoding a `NonZeroU32`"
355    core::num::NonZeroU64, "unexpected 0 when decoding a `NonZeroU64`"
356    core::num::NonZeroI8,  "unexpected 0 when decoding a `NonZeroI8`"
357    core::num::NonZeroI16, "unexpected 0 when decoding a `NonZeroI16`"
358    core::num::NonZeroI32, "unexpected 0 when decoding a `NonZeroI32`"
359    core::num::NonZeroI64, "unexpected 0 when decoding a `NonZeroI64`"
360}
361
362#[cfg(any(target_pointer_width = "16", target_pointer_width = "32", target_pointer_width = "64"))]
363decode_nonzero! {
364    core::num::NonZeroUsize,  "unexpected 0 when decoding a `NonZeroUsize`"
365    core::num::NonZeroIsize,  "unexpected 0 when decoding a `NonZeroIsize`"
366}
367
368#[cfg(any(atomic32, atomic64))]
369macro_rules! decode_atomic {
370    ($($t:ty)*) => {
371        $(
372            impl<'b, C> Decode<'b, C> for $t {
373                fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
374                    d.decode_with(ctx).map(<$t>::new)
375                }
376            }
377        )*
378    }
379}
380
381#[cfg(atomic32)]
382decode_atomic! {
383    core::sync::atomic::AtomicBool
384    core::sync::atomic::AtomicU8
385    core::sync::atomic::AtomicU16
386    core::sync::atomic::AtomicU32
387    core::sync::atomic::AtomicUsize
388    core::sync::atomic::AtomicI8
389    core::sync::atomic::AtomicI16
390    core::sync::atomic::AtomicI32
391    core::sync::atomic::AtomicIsize
392}
393
394#[cfg(atomic64)]
395decode_atomic! {
396    core::sync::atomic::AtomicBool
397    core::sync::atomic::AtomicU8
398    core::sync::atomic::AtomicU16
399    core::sync::atomic::AtomicU32
400    core::sync::atomic::AtomicU64
401    core::sync::atomic::AtomicUsize
402    core::sync::atomic::AtomicI8
403    core::sync::atomic::AtomicI16
404    core::sync::atomic::AtomicI32
405    core::sync::atomic::AtomicI64
406    core::sync::atomic::AtomicIsize
407}
408
409#[cfg(feature = "alloc")]
410macro_rules! decode_sequential {
411    ($($t:ty, $push:ident)*) => {
412        $(
413            impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for $t {
414                fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
415                    let iter: ArrayIterWithCtx<C, T> = d.array_iter_with(ctx)?;
416                    let mut v = <$t>::new();
417                    for x in iter {
418                        v.$push(x?)
419                    }
420                    Ok(v)
421                }
422            }
423        )*
424    }
425}
426
427#[cfg(feature = "alloc")]
428decode_sequential! {
429    alloc::vec::Vec<T>, push
430    alloc::collections::VecDeque<T>, push_back
431    alloc::collections::LinkedList<T>, push_back
432}
433
434struct ArrayVec<T, const N: usize>{
435    len: usize,
436    buffer: [MaybeUninit<T>; N],
437}
438
439impl <T, const N: usize> ArrayVec<T, N> {
440    const ELEM: MaybeUninit<T> = MaybeUninit::uninit();
441
442    fn new() -> Self {
443        Self {
444            len: 0,
445            buffer: [Self::ELEM; N]
446        }
447    }
448
449    fn into_array(self) -> Result<[T; N], Self> {
450        if self.len == N {
451            let array = unsafe {
452                (&self.buffer as *const [MaybeUninit<T>; N] as *const [T; N]).read()
453            };
454
455            // We don't want `self`'s destructor to be called because that would drop all the
456            // items in the array
457            core::mem::forget(self);
458
459            Ok(array)
460        } else {
461            Err(self)
462        }
463    }
464
465    fn push(&mut self, item: T) -> Result<(), T> {
466        if let Some(slot) = self.buffer.get_mut(self.len) {
467            slot.write(item);
468            self.len += 1;
469            Ok(())
470        } else {
471            Err(item)
472        }
473    }
474}
475
476impl <T, const N: usize> core::ops::Drop for ArrayVec<T, N> {
477    fn drop(&mut self) {
478        unsafe {
479            let s = core::slice::from_raw_parts_mut(self.buffer.as_mut_ptr() as *mut T, self.len);
480            core::ptr::drop_in_place(s)
481        }
482    }
483}
484
485impl<'b, C, T: Decode<'b, C>, const N: usize> Decode<'b, C> for [T; N] {
486    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
487        let p = d.position();
488        let iter: ArrayIterWithCtx<C, T> = d.array_iter_with(ctx)?;
489        let mut a = ArrayVec::<T, N>::new();
490        for x in iter {
491            a.push(x?).map_err(|_| {
492                #[cfg(feature = "alloc")]
493                let msg = &alloc::format!("array has more than {N} elements");
494                #[cfg(not(feature = "alloc"))]
495                let msg = "array has too many elements";
496                Error::message(msg).at(p)
497            })?;
498        }
499        a.into_array().map_err(|_| {
500            #[cfg(feature = "alloc")]
501            let msg = &alloc::format!("array has less than {N} elements");
502            #[cfg(not(feature = "alloc"))]
503            let msg = "array has too few elements";
504            Error::message(msg).at(p)
505        })
506    }
507}
508
509macro_rules! decode_tuples {
510    ($( $len:expr => { $($T:ident)+ } )+) => {
511        $(
512            impl<'b, Ctx, $($T: Decode<'b, Ctx>),+> Decode<'b, Ctx> for ($($T,)+) {
513                fn decode(d: &mut Decoder<'b>, ctx: &mut Ctx) -> Result<Self, Error> {
514                    let p = d.position();
515                    let n = d.array()?;
516                    if n != Some($len) {
517                        return Err(Error::message(concat!("invalid ", $len, "-tuple length")).at(p))
518                    }
519                    Ok(($($T::decode(d, ctx)?,)+))
520                }
521            }
522        )+
523    }
524}
525
526decode_tuples! {
527    1  => { A }
528    2  => { A B }
529    3  => { A B C }
530    4  => { A B C D }
531    5  => { A B C D E }
532    6  => { A B C D E F }
533    7  => { A B C D E F G }
534    8  => { A B C D E F G H }
535    9  => { A B C D E F G H I }
536    10 => { A B C D E F G H I J }
537    11 => { A B C D E F G H I J K }
538    12 => { A B C D E F G H I J K L }
539    13 => { A B C D E F G H I J K L M }
540    14 => { A B C D E F G H I J K L M N }
541    15 => { A B C D E F G H I J K L M N O }
542    16 => { A B C D E F G H I J K L M N O P }
543}
544
545macro_rules! decode_fields {
546    ($d:ident $c:ident | $($n:literal $x:ident => $t:ty ; $msg:literal)*) => {
547        $(let mut $x : core::option::Option<$t> = None;)*
548
549        let p = $d.position();
550
551        match $d.array()? {
552            Some(n) => for i in 0 .. n {
553                match i {
554                    $($n => $x = Some(Decode::decode($d, $c)?),)*
555                    _    => $d.skip()?
556                }
557            }
558            None => {
559                let mut i = 0;
560                while $d.datatype()? != crate::data::Type::Break {
561                    match i {
562                        $($n => $x = Some(Decode::decode($d, $c)?),)*
563                        _    => $d.skip()?
564                    }
565                    i += 1
566                }
567                $d.skip()?
568            }
569        }
570
571        $(let $x = if let Some(x) = $x {
572            x
573        } else {
574            return Err(Error::missing_value($n).at(p).with_message($msg))
575        };)*
576    }
577}
578
579impl<'b, C> Decode<'b, C> for core::time::Duration {
580    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
581        decode_fields! { d ctx |
582            0 secs  => u64 ; "Duration::secs"
583            1 nanos => u32 ; "Duration::nanos"
584        }
585        Ok(core::time::Duration::new(secs, nanos))
586    }
587}
588
589#[cfg(feature = "std")]
590impl<'b, C> Decode<'b, C> for std::time::SystemTime {
591    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
592        let p = d.position();
593        std::time::UNIX_EPOCH
594            .checked_add(d.decode_with(ctx)?)
595            .ok_or_else(|| Error::message("duration value can not represent system time").at(p))
596    }
597}
598
599impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::cell::Cell<T> {
600    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
601        d.decode_with(ctx).map(core::cell::Cell::new)
602    }
603}
604
605impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::cell::RefCell<T> {
606    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
607        d.decode_with(ctx).map(core::cell::RefCell::new)
608    }
609}
610
611#[cfg(feature = "std")]
612impl<'a, 'b: 'a, C> Decode<'b, C> for &'a std::path::Path {
613    fn decode(d: &mut Decoder<'b>, _: &mut C) -> Result<Self, Error> {
614        d.str().map(std::path::Path::new)
615    }
616}
617
618#[cfg(feature = "std")]
619impl<'b, C> Decode<'b, C> for Box<std::path::Path> {
620    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
621        d.decode_with(ctx).map(std::path::PathBuf::into_boxed_path)
622    }
623}
624
625#[cfg(feature = "std")]
626impl<'b, C> Decode<'b, C> for std::path::PathBuf {
627    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
628        d.decode_with(ctx).map(std::path::Path::to_path_buf)
629    }
630}
631
632#[cfg(feature = "std")]
633impl<'b, C> Decode<'b, C> for std::net::IpAddr {
634    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
635        let p = d.position();
636        if Some(2) != d.array()? {
637            return Err(Error::message("expected enum (2-element array)").at(p))
638        }
639        let p = d.position();
640        match d.i64()? {
641            0 => Ok(std::net::Ipv4Addr::decode(d, ctx)?.into()),
642            1 => Ok(std::net::Ipv6Addr::decode(d, ctx)?.into()),
643            n => Err(Error::unknown_variant(n).at(p))
644        }
645    }
646}
647
648#[cfg(feature = "std")]
649impl<'b, C> Decode<'b, C> for std::net::Ipv4Addr {
650    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
651        let octets: crate::bytes::ByteArray<4> = Decode::decode(d, ctx)?;
652        Ok(<[u8; 4]>::from(octets).into())
653    }
654}
655
656#[cfg(feature = "std")]
657impl<'b, C> Decode<'b, C> for std::net::Ipv6Addr {
658    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
659        let octets: crate::bytes::ByteArray<16> = Decode::decode(d, ctx)?;
660        Ok(<[u8; 16]>::from(octets).into())
661    }
662}
663
664#[cfg(feature = "std")]
665impl<'b, C> Decode<'b, C> for std::net::SocketAddr {
666    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
667        let p = d.position();
668        if Some(2) != d.array()? {
669            return Err(Error::message("expected enum (2-element array)").at(p))
670        }
671        let p = d.position();
672        match d.i64()? {
673            0 => Ok(std::net::SocketAddrV4::decode(d, ctx)?.into()),
674            1 => Ok(std::net::SocketAddrV6::decode(d, ctx)?.into()),
675            n => Err(Error::unknown_variant(n).at(p))
676        }
677    }
678}
679
680#[cfg(feature = "std")]
681impl<'b, C> Decode<'b, C> for std::net::SocketAddrV4 {
682    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
683        decode_fields! { d ctx |
684            0 ip   => std::net::Ipv4Addr ; "SocketAddrV4::ip"
685            1 port => u16                ; "SocketAddrV4::port"
686        }
687        Ok(std::net::SocketAddrV4::new(ip, port))
688    }
689}
690
691#[cfg(feature = "std")]
692impl<'b, C> Decode<'b, C> for std::net::SocketAddrV6 {
693    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
694        decode_fields! { d ctx |
695            0 ip   => std::net::Ipv6Addr ; "SocketAddrV6::ip"
696            1 port => u16                ; "SocketAddrV6::port"
697        }
698        Ok(std::net::SocketAddrV6::new(ip, port, 0, 0))
699    }
700}
701
702impl<'b, C, T: Decode<'b, C>> Decode<'b,C > for core::ops::Range<T> {
703    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
704        decode_fields! { d ctx |
705            0 start => T ; "Range::start"
706            1 end   => T ; "Range::end"
707        }
708        Ok(core::ops::Range { start, end })
709    }
710}
711
712impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::ops::RangeFrom<T> {
713    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
714        decode_fields! { d ctx |
715            0 start => T ; "RangeFrom::start"
716        }
717        Ok(core::ops::RangeFrom { start })
718    }
719}
720
721impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::ops::RangeTo<T> {
722    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
723        decode_fields! { d ctx |
724            0 end => T ; "RangeTo::end"
725        }
726        Ok(core::ops::RangeTo { end })
727    }
728}
729
730impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::ops::RangeToInclusive<T> {
731    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
732        decode_fields! { d ctx |
733            0 end => T ; "RangeToInclusive::end"
734        }
735        Ok(core::ops::RangeToInclusive { end })
736    }
737}
738
739impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::ops::RangeInclusive<T> {
740    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
741        decode_fields! { d ctx |
742            0 start => T ; "RangeInclusive::start"
743            1 end   => T ; "RangeInclusive::end"
744        }
745        Ok(core::ops::RangeInclusive::new(start, end))
746    }
747}
748
749impl<'b, C, T: Decode<'b, C>> Decode<'b, C> for core::ops::Bound<T> {
750    fn decode(d: &mut Decoder<'b>, ctx: &mut C) -> Result<Self, Error> {
751        let p = d.position();
752        if Some(2) != d.array()? {
753            return Err(Error::message("expected enum (2-element array)").at(p))
754        }
755        let p = d.position();
756        match d.i64()? {
757            0 => d.decode_with(ctx).map(core::ops::Bound::Included),
758            1 => d.decode_with(ctx).map(core::ops::Bound::Excluded),
759            2 => d.skip().map(|_| core::ops::Bound::Unbounded),
760            n => Err(Error::unknown_variant(n).at(p))
761        }
762    }
763}
764