Skip to main content

sacp_cbor/
codec.rs

1#[cfg(feature = "alloc")]
2use alloc::collections::{BTreeMap, BTreeSet};
3#[cfg(feature = "alloc")]
4use alloc::string::String;
5#[cfg(feature = "alloc")]
6use alloc::vec::Vec;
7
8#[cfg(feature = "alloc")]
9use crate::alloc_util;
10use crate::canonical::CanonicalCborRef;
11use crate::profile::{validate_f64_bits, MAX_SAFE_INTEGER};
12use crate::query::{CborKind, CborValueRef};
13use crate::wire::{self, Cursor};
14use crate::{CborError, DecodeLimits, ErrorCode};
15
16#[cfg(feature = "alloc")]
17use crate::encode::Encoder;
18#[cfg(feature = "alloc")]
19use crate::CanonicalCbor;
20#[cfg(feature = "alloc")]
21use crate::{BigInt, CborInteger};
22
23#[cfg(feature = "std")]
24use std::collections::HashMap;
25#[cfg(feature = "std")]
26use std::hash::BuildHasher;
27
28/// A CBOR map represented as ordered key/value entries.
29#[cfg(feature = "alloc")]
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct MapEntries<K, V>(pub Vec<(K, V)>);
32
33#[cfg(feature = "alloc")]
34impl<K, V> MapEntries<K, V> {
35    /// Wrap an existing vector of entries.
36    #[must_use]
37    pub const fn new(entries: Vec<(K, V)>) -> Self {
38        Self(entries)
39    }
40}
41
42/// Streaming decoder over canonical CBOR bytes.
43pub struct Decoder<'de, const CHECKED: bool> {
44    cursor: Cursor<'de, CborError>,
45    limits: DecodeLimits,
46    depth: usize,
47    items_seen: usize,
48    poison: Option<CborError>,
49}
50
51/// Decoder that enforces canonical constraints while decoding.
52pub type CheckedDecoder<'de> = Decoder<'de, true>;
53/// Decoder that trusts inputs are already canonical.
54pub type TrustedDecoder<'de> = Decoder<'de, false>;
55
56/// Array decoder guard that manages depth and length.
57pub struct ArrayDecoder<'a, 'de, const CHECKED: bool> {
58    decoder: &'a mut Decoder<'de, CHECKED>,
59    remaining: usize,
60    entered: bool,
61}
62
63/// Map decoder guard that manages depth, length, and key ordering.
64pub struct MapDecoder<'a, 'de, const CHECKED: bool> {
65    decoder: &'a mut Decoder<'de, CHECKED>,
66    remaining: usize,
67    entered: bool,
68    pending_value: bool,
69    prev_key_range: Option<(usize, usize)>,
70}
71
72impl<const CHECKED: bool> Drop for ArrayDecoder<'_, '_, CHECKED> {
73    fn drop(&mut self) {
74        if self.entered {
75            if self.remaining != 0 {
76                let off = self.decoder.position();
77                self.decoder.poison(ErrorCode::MalformedCanonical, off);
78            }
79            self.decoder.exit_container();
80        }
81    }
82}
83
84impl<const CHECKED: bool> Drop for MapDecoder<'_, '_, CHECKED> {
85    fn drop(&mut self) {
86        if self.entered {
87            if self.remaining != 0 || self.pending_value {
88                let off = self.decoder.position();
89                self.decoder.poison(ErrorCode::MalformedCanonical, off);
90            }
91            self.decoder.exit_container();
92        }
93    }
94}
95
96impl<'de> Decoder<'de, true> {
97    /// Construct a decoder that enforces canonical constraints while decoding.
98    ///
99    /// # Errors
100    ///
101    /// Returns `MessageLenLimitExceeded` if `bytes` exceeds the input limit.
102    pub const fn new_checked(bytes: &'de [u8], limits: DecodeLimits) -> Result<Self, CborError> {
103        Self::new_with(bytes, limits)
104    }
105}
106
107impl<'de> Decoder<'de, false> {
108    /// Construct a decoder over canonical bytes with the provided limits.
109    ///
110    /// This assumes the input is already canonical.
111    ///
112    /// # Errors
113    ///
114    /// Returns `MessageLenLimitExceeded` if `bytes` exceeds the input limit.
115    pub const fn new_trusted(
116        canon: CanonicalCborRef<'de>,
117        limits: DecodeLimits,
118    ) -> Result<Self, CborError> {
119        Self::new_with(canon.as_bytes(), limits)
120    }
121}
122
123impl<'de, const CHECKED: bool> Decoder<'de, CHECKED> {
124    const fn new_with(bytes: &'de [u8], limits: DecodeLimits) -> Result<Self, CborError> {
125        if bytes.len() > limits.max_input_bytes {
126            return Err(CborError::new(ErrorCode::MessageLenLimitExceeded, 0));
127        }
128        Ok(Self {
129            cursor: Cursor::with_pos(bytes, 0),
130            limits,
131            depth: 0,
132            items_seen: 0,
133            poison: None,
134        })
135    }
136
137    /// Return the current byte offset in the input.
138    #[must_use]
139    #[inline]
140    pub const fn position(&self) -> usize {
141        self.cursor.position()
142    }
143
144    #[inline]
145    pub(crate) const fn data(&self) -> &'de [u8] {
146        self.cursor.data()
147    }
148
149    #[inline]
150    fn peek_u8(&self) -> Result<u8, CborError> {
151        self.check_poison()?;
152        let off = self.cursor.position();
153        self.data()
154            .get(off)
155            .copied()
156            .ok_or_else(|| CborError::new(ErrorCode::UnexpectedEof, off))
157    }
158
159    #[inline]
160    fn read_header(&mut self) -> Result<(u8, u8, usize), CborError> {
161        self.check_poison()?;
162        let off = self.cursor.position();
163        let ib = self.cursor.read_u8()?;
164        Ok((ib >> 5, ib & 0x1f, off))
165    }
166
167    #[inline]
168    fn read_uint_arg(&mut self, ai: u8, off: usize) -> Result<u64, CborError> {
169        wire::read_uint_arg::<CHECKED, CborError>(&mut self.cursor, ai, off)
170    }
171
172    #[inline]
173    fn read_len(&mut self, ai: u8, off: usize) -> Result<usize, CborError> {
174        wire::read_len::<CHECKED, CborError>(&mut self.cursor, ai, off)
175    }
176
177    #[inline]
178    fn bump_items(&mut self, add: usize, off: usize) -> Result<(), CborError> {
179        self.items_seen = self
180            .items_seen
181            .checked_add(add)
182            .ok_or_else(|| CborError::new(ErrorCode::LengthOverflow, off))?;
183        if self.items_seen > self.limits.max_total_items {
184            return Err(CborError::new(ErrorCode::TotalItemsLimitExceeded, off));
185        }
186        Ok(())
187    }
188
189    #[inline]
190    fn enter_container(&mut self, len: usize, off: usize) -> Result<bool, CborError> {
191        let next_depth = self.depth + 1;
192        if next_depth > self.limits.max_depth {
193            return Err(CborError::new(ErrorCode::DepthLimitExceeded, off));
194        }
195        if len == 0 {
196            return Ok(false);
197        }
198        self.depth = next_depth;
199        Ok(true)
200    }
201
202    #[inline]
203    fn exit_container(&mut self) {
204        debug_assert!(self.depth > 0);
205        self.depth = self.depth.saturating_sub(1);
206    }
207
208    #[inline]
209    const fn check_poison(&self) -> Result<(), CborError> {
210        if let Some(err) = self.poison {
211            return Err(err);
212        }
213        Ok(())
214    }
215
216    #[inline]
217    fn poison(&mut self, code: ErrorCode, offset: usize) {
218        if self.poison.is_none() {
219            self.poison = Some(CborError::new(code, offset));
220        }
221    }
222
223    #[inline]
224    fn parse_text_from_header(&mut self, off: usize, ai: u8) -> Result<&'de str, CborError> {
225        wire::parse_text_from_header::<CHECKED, CborError>(
226            &mut self.cursor,
227            Some(&self.limits),
228            off,
229            ai,
230        )
231    }
232
233    #[inline]
234    fn parse_bytes_from_header(&mut self, off: usize, ai: u8) -> Result<&'de [u8], CborError> {
235        let len = self.read_len(ai, off)?;
236        if len > self.limits.max_bytes_len {
237            return Err(CborError::new(ErrorCode::BytesLenLimitExceeded, off));
238        }
239        self.cursor.read_exact(len)
240    }
241
242    #[inline]
243    fn parse_bignum(&mut self, off: usize, ai: u8) -> Result<(bool, &'de [u8]), CborError> {
244        wire::parse_bignum::<CHECKED, CborError>(&mut self.cursor, Some(&self.limits), off, ai)
245    }
246
247    fn parse_safe_i64(&mut self) -> Result<i64, CborError> {
248        let (major, ai, off) = self.read_header()?;
249        match major {
250            0 => {
251                let v = self.read_uint_arg(ai, off)?;
252                if CHECKED && v > MAX_SAFE_INTEGER {
253                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
254                }
255                i64::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
256            }
257            1 => {
258                let n = self.read_uint_arg(ai, off)?;
259                if CHECKED && n >= MAX_SAFE_INTEGER {
260                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
261                }
262                let n = i64::try_from(n)
263                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
264                Ok(-1 - n)
265            }
266            _ => Err(CborError::new(ErrorCode::ExpectedInteger, off)),
267        }
268    }
269
270    fn parse_safe_u64(&mut self) -> Result<u64, CborError> {
271        let off = self.position();
272        let v = self.parse_safe_i64()?;
273        u64::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
274    }
275
276    fn parse_float64(&mut self) -> Result<f64, CborError> {
277        let (major, ai, off) = self.read_header()?;
278        if major != 7 {
279            return Err(CborError::new(ErrorCode::ExpectedFloat, off));
280        }
281        if ai != 27 {
282            if !CHECKED {
283                return Err(CborError::new(ErrorCode::ExpectedFloat, off));
284            }
285            return match ai {
286                24 => {
287                    let simple = self.cursor.read_u8()?;
288                    if simple < 24 {
289                        return Err(CborError::new(ErrorCode::NonCanonicalEncoding, off));
290                    }
291                    Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
292                }
293                28..=30 => Err(CborError::new(ErrorCode::ReservedAdditionalInfo, off)),
294                25 | 26 => Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off)),
295                _ => Err(CborError::new(ErrorCode::ExpectedFloat, off)),
296            };
297        }
298        let bits = self.cursor.read_be_u64()?;
299        if CHECKED {
300            validate_f64_bits(bits).map_err(|code| CborError::new(code, off))?;
301        }
302        Ok(f64::from_bits(bits))
303    }
304
305    fn parse_bool(&mut self) -> Result<bool, CborError> {
306        let (major, ai, off) = self.read_header()?;
307        if major != 7 {
308            return Err(CborError::new(ErrorCode::ExpectedBool, off));
309        }
310        match ai {
311            20 => Ok(false),
312            21 => Ok(true),
313            22 | 27 => Err(CborError::new(ErrorCode::ExpectedBool, off)),
314            24 => {
315                if !CHECKED {
316                    return Err(CborError::new(ErrorCode::ExpectedBool, off));
317                }
318                let simple = self.cursor.read_u8()?;
319                if simple < 24 {
320                    return Err(CborError::new(ErrorCode::NonCanonicalEncoding, off));
321                }
322                Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
323            }
324            28..=30 => {
325                if CHECKED {
326                    Err(CborError::new(ErrorCode::ReservedAdditionalInfo, off))
327                } else {
328                    Err(CborError::new(ErrorCode::ExpectedBool, off))
329                }
330            }
331            _ => {
332                if CHECKED {
333                    Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
334                } else {
335                    Err(CborError::new(ErrorCode::ExpectedBool, off))
336                }
337            }
338        }
339    }
340
341    fn parse_null(&mut self) -> Result<(), CborError> {
342        let (major, ai, off) = self.read_header()?;
343        if major != 7 {
344            return Err(CborError::new(ErrorCode::ExpectedNull, off));
345        }
346        match ai {
347            22 => Ok(()),
348            20 | 21 | 27 => Err(CborError::new(ErrorCode::ExpectedNull, off)),
349            24 => {
350                if !CHECKED {
351                    return Err(CborError::new(ErrorCode::ExpectedNull, off));
352                }
353                let simple = self.cursor.read_u8()?;
354                if simple < 24 {
355                    return Err(CborError::new(ErrorCode::NonCanonicalEncoding, off));
356                }
357                Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
358            }
359            28..=30 => {
360                if CHECKED {
361                    Err(CborError::new(ErrorCode::ReservedAdditionalInfo, off))
362                } else {
363                    Err(CborError::new(ErrorCode::ExpectedNull, off))
364                }
365            }
366            _ => {
367                if CHECKED {
368                    Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
369                } else {
370                    Err(CborError::new(ErrorCode::ExpectedNull, off))
371                }
372            }
373        }
374    }
375
376    fn parse_bytes(&mut self) -> Result<&'de [u8], CborError> {
377        let (major, ai, off) = self.read_header()?;
378        if major != 2 {
379            return Err(CborError::new(ErrorCode::ExpectedBytes, off));
380        }
381        self.parse_bytes_from_header(off, ai)
382    }
383
384    fn parse_text(&mut self) -> Result<&'de str, CborError> {
385        let (major, ai, off) = self.read_header()?;
386        if major != 3 {
387            return Err(CborError::new(ErrorCode::ExpectedText, off));
388        }
389        self.parse_text_from_header(off, ai)
390    }
391
392    /// Decode an array header and return a guard for its elements.
393    ///
394    /// # Errors
395    ///
396    /// Returns `ExpectedArray` if the next value is not an array, or a limit error.
397    pub fn array(&mut self) -> Result<ArrayDecoder<'_, 'de, CHECKED>, CborError> {
398        let (major, ai, off) = self.read_header()?;
399        if major != 4 {
400            return Err(CborError::new(ErrorCode::ExpectedArray, off));
401        }
402        let len = self.read_len(ai, off)?;
403        if len > self.limits.max_array_len {
404            return Err(CborError::new(ErrorCode::ArrayLenLimitExceeded, off));
405        }
406        self.bump_items(len, off)?;
407        let entered = self.enter_container(len, off)?;
408        Ok(ArrayDecoder {
409            decoder: self,
410            remaining: len,
411            entered,
412        })
413    }
414
415    /// Decode a map header and return a guard for its entries.
416    ///
417    /// # Errors
418    ///
419    /// Returns `ExpectedMap` if the next value is not a map, or a limit error.
420    pub fn map(&mut self) -> Result<MapDecoder<'_, 'de, CHECKED>, CborError> {
421        let (major, ai, off) = self.read_header()?;
422        if major != 5 {
423            return Err(CborError::new(ErrorCode::ExpectedMap, off));
424        }
425        let len = self.read_len(ai, off)?;
426        if len > self.limits.max_map_len {
427            return Err(CborError::new(ErrorCode::MapLenLimitExceeded, off));
428        }
429        let items = len
430            .checked_mul(2)
431            .ok_or_else(|| CborError::new(ErrorCode::LengthOverflow, off))?;
432        self.bump_items(items, off)?;
433        let entered = self.enter_container(len, off)?;
434        Ok(MapDecoder {
435            decoder: self,
436            remaining: len,
437            entered,
438            pending_value: false,
439            prev_key_range: None,
440        })
441    }
442
443    /// Skip exactly one CBOR value while enforcing decode limits.
444    ///
445    /// # Errors
446    ///
447    /// Returns a decode error if the value is malformed or violates limits.
448    pub fn skip_value(&mut self) -> Result<(), CborError> {
449        self.check_poison()?;
450        wire::skip_one_value::<CHECKED, CborError>(
451            &mut self.cursor,
452            Some(&self.limits),
453            &mut self.items_seen,
454            self.depth,
455        )
456    }
457
458    /// Peek at the kind of the next CBOR value without consuming it.
459    ///
460    /// # Errors
461    ///
462    /// Returns a decode error if the header is malformed.
463    pub fn peek_kind(&self) -> Result<CborKind, CborError> {
464        self.check_poison()?;
465        let mut pos = self.cursor.position();
466        let off = pos;
467        let ib = wire::read_u8(self.data(), &mut pos)?;
468        let major = ib >> 5;
469        let ai = ib & 0x1f;
470        match major {
471            0 | 1 => Ok(CborKind::Integer),
472            2 => Ok(CborKind::Bytes),
473            3 => Ok(CborKind::Text),
474            4 => Ok(CborKind::Array),
475            5 => Ok(CborKind::Map),
476            6 => {
477                let tag =
478                    wire::read_uint_arg_at::<CHECKED, CborError>(self.data(), &mut pos, ai, off)?;
479                match tag {
480                    2 | 3 => Ok(CborKind::Integer),
481                    _ => Err(CborError::new(ErrorCode::MalformedCanonical, off)),
482                }
483            }
484            7 => match ai {
485                20 | 21 => Ok(CborKind::Bool),
486                22 => Ok(CborKind::Null),
487                27 => Ok(CborKind::Float),
488                24 => {
489                    if !CHECKED {
490                        return Err(CborError::new(ErrorCode::MalformedCanonical, off));
491                    }
492                    let simple = wire::read_u8(self.data(), &mut pos)?;
493                    if simple < 24 {
494                        Err(CborError::new(ErrorCode::NonCanonicalEncoding, off))
495                    } else {
496                        Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
497                    }
498                }
499                28..=30 => {
500                    if CHECKED {
501                        Err(CborError::new(ErrorCode::ReservedAdditionalInfo, off))
502                    } else {
503                        Err(CborError::new(ErrorCode::MalformedCanonical, off))
504                    }
505                }
506                _ => {
507                    if CHECKED {
508                        Err(CborError::new(ErrorCode::UnsupportedSimpleValue, off))
509                    } else {
510                        Err(CborError::new(ErrorCode::MalformedCanonical, off))
511                    }
512                }
513            },
514            _ => Err(CborError::new(ErrorCode::MalformedCanonical, off)),
515        }
516    }
517}
518
519impl<'de, const CHECKED: bool> ArrayDecoder<'_, 'de, CHECKED> {
520    /// Remaining elements in the array.
521    #[inline]
522    #[must_use]
523    pub const fn remaining(&self) -> usize {
524        self.remaining
525    }
526
527    /// Decode the next array element.
528    ///
529    /// Returns `Ok(None)` when the array is exhausted.
530    ///
531    /// # Errors
532    ///
533    /// Returns an error if decoding fails.
534    pub fn next_value<T: CborDecode<'de>>(&mut self) -> Result<Option<T>, CborError> {
535        if self.remaining == 0 {
536            return Ok(None);
537        }
538        let value = T::decode(self.decoder)?;
539        self.remaining -= 1;
540        Ok(Some(value))
541    }
542
543    /// Decode the next array element using a custom decoder.
544    ///
545    /// # Errors
546    ///
547    /// Returns an error if decoding fails.
548    pub fn decode_next<F, T>(&mut self, f: F) -> Result<Option<T>, CborError>
549    where
550        F: FnOnce(&mut Decoder<'de, CHECKED>) -> Result<T, CborError>,
551    {
552        if self.remaining == 0 {
553            return Ok(None);
554        }
555        let value = f(self.decoder)?;
556        self.remaining -= 1;
557        Ok(Some(value))
558    }
559
560    /// Skip all remaining elements in the array.
561    ///
562    /// # Errors
563    ///
564    /// Returns an error if skipping fails.
565    pub fn skip_remaining(&mut self) -> Result<(), CborError> {
566        while self.remaining > 0 {
567            self.decoder.skip_value()?;
568            self.remaining -= 1;
569        }
570        Ok(())
571    }
572}
573
574impl<'de, const CHECKED: bool> MapDecoder<'_, 'de, CHECKED> {
575    /// Remaining entries in the map.
576    #[inline]
577    #[must_use]
578    pub const fn remaining(&self) -> usize {
579        self.remaining
580    }
581
582    /// Decode the next map key as text.
583    ///
584    /// Returns `Ok(None)` when the map is exhausted.
585    ///
586    /// # Errors
587    ///
588    /// Returns an error if decoding fails or the map is malformed.
589    pub fn next_key(&mut self) -> Result<Option<&'de str>, CborError> {
590        if self.pending_value {
591            return Err(CborError::new(
592                ErrorCode::MalformedCanonical,
593                self.decoder.position(),
594            ));
595        }
596        if self.remaining == 0 {
597            return Ok(None);
598        }
599        let key_start = self.decoder.position();
600        let (major, ai, off) = self.decoder.read_header()?;
601        if major != 3 {
602            return Err(CborError::new(ErrorCode::MapKeyMustBeText, off));
603        }
604        let key = self.decoder.parse_text_from_header(off, ai)?;
605        let key_end = self.decoder.position();
606        if CHECKED {
607            wire::check_map_key_order(
608                self.decoder.data(),
609                &mut self.prev_key_range,
610                key_start,
611                key_end,
612            )?;
613        }
614        self.pending_value = true;
615        Ok(Some(key))
616    }
617
618    /// Decode the value corresponding to the last returned key.
619    ///
620    /// # Errors
621    ///
622    /// Returns an error if decoding fails or the map is malformed.
623    pub fn next_value<T: CborDecode<'de>>(&mut self) -> Result<T, CborError> {
624        self.decode_value(T::decode)
625    }
626
627    /// Decode the value corresponding to the last returned key using a custom decoder.
628    ///
629    /// # Errors
630    ///
631    /// Returns an error if decoding fails or the map is malformed.
632    pub fn decode_value<F, T>(&mut self, f: F) -> Result<T, CborError>
633    where
634        F: FnOnce(&mut Decoder<'de, CHECKED>) -> Result<T, CborError>,
635    {
636        if !self.pending_value {
637            return Err(CborError::new(
638                ErrorCode::MalformedCanonical,
639                self.decoder.position(),
640            ));
641        }
642        let value = f(self.decoder)?;
643        self.pending_value = false;
644        self.remaining -= 1;
645        Ok(value)
646    }
647
648    /// Decode the next key/value entry in the map.
649    ///
650    /// # Errors
651    ///
652    /// Returns an error if decoding fails or the map is malformed.
653    pub fn next_entry<V: CborDecode<'de>>(&mut self) -> Result<Option<(&'de str, V)>, CborError> {
654        let Some(key) = self.next_key()? else {
655            return Ok(None);
656        };
657        let value = self.next_value()?;
658        Ok(Some((key, value)))
659    }
660
661    /// Skip all remaining map entries.
662    ///
663    /// # Errors
664    ///
665    /// Returns an error if skipping fails or the map is malformed.
666    pub fn skip_remaining(&mut self) -> Result<(), CborError> {
667        while self.remaining > 0 {
668            if !self.pending_value {
669                let _ = self.next_key()?;
670            }
671            self.decoder.skip_value()?;
672            self.pending_value = false;
673            self.remaining -= 1;
674        }
675        Ok(())
676    }
677}
678
679/// Decode a value from a streaming decoder.
680pub trait CborDecode<'de>: Sized {
681    /// Decode `Self` from a streaming decoder.
682    ///
683    /// # Errors
684    ///
685    /// Returns an error if the CBOR value does not match the expected type or violates profile
686    /// constraints.
687    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError>;
688}
689
690#[cfg(feature = "alloc")]
691/// Encode a value into canonical CBOR bytes using the streaming encoder.
692pub trait CborEncode {
693    /// Encode `self` into the provided encoder.
694    ///
695    /// # Errors
696    ///
697    /// Returns an error if encoding fails.
698    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError>;
699}
700
701#[cfg(feature = "alloc")]
702/// Marker trait for values that can appear as CBOR array elements.
703pub trait CborArrayElem {}
704
705/// Validate canonical CBOR and decode a value using `CborDecode`.
706///
707/// # Errors
708///
709/// Returns an error if the input is not canonical CBOR or if decoding fails.
710pub fn decode<'de, T: CborDecode<'de>>(
711    bytes: &'de [u8],
712    limits: DecodeLimits,
713) -> Result<T, CborError> {
714    let mut decoder = Decoder::<true>::new_checked(bytes, limits)?;
715    let value = T::decode(&mut decoder)?;
716    if decoder.position() != bytes.len() {
717        return Err(CborError::new(ErrorCode::TrailingBytes, decoder.position()));
718    }
719    Ok(value)
720}
721
722/// Decode a value from validated canonical bytes.
723///
724/// # Errors
725///
726/// Returns an error if decoding fails.
727pub fn decode_canonical<'de, T: CborDecode<'de>>(
728    canon: CanonicalCborRef<'de>,
729) -> Result<T, CborError> {
730    let limits = DecodeLimits::for_bytes(canon.len());
731    let mut decoder = Decoder::<false>::new_trusted(canon, limits)?;
732    let value = T::decode(&mut decoder)?;
733    if decoder.position() != canon.len() {
734        return Err(CborError::new(ErrorCode::TrailingBytes, decoder.position()));
735    }
736    Ok(value)
737}
738
739/// Decode a value from owned canonical bytes.
740///
741/// # Errors
742///
743/// Returns an error if decoding fails.
744#[cfg(feature = "alloc")]
745pub fn decode_canonical_owned<'de, T: CborDecode<'de>>(
746    canon: &'de CanonicalCbor,
747) -> Result<T, CborError> {
748    decode_canonical(canon.as_ref())
749}
750
751#[cfg(feature = "alloc")]
752/// Encode a value into canonical CBOR bytes.
753///
754/// # Errors
755///
756/// Returns an error if encoding fails.
757pub fn encode_to_vec<T: CborEncode>(value: &T) -> Result<Vec<u8>, CborError> {
758    let mut enc = Encoder::new();
759    value.encode(&mut enc)?;
760    Ok(enc.into_vec())
761}
762
763#[cfg(feature = "alloc")]
764/// Encode a value into an existing encoder, reusing its capacity.
765///
766/// # Errors
767///
768/// Returns an error if encoding fails.
769pub fn encode_into<T: CborEncode>(enc: &mut Encoder, value: &T) -> Result<(), CborError> {
770    enc.clear();
771    value.encode(enc)
772}
773
774#[cfg(feature = "alloc")]
775/// Encode a value into owned canonical CBOR bytes.
776///
777/// # Errors
778///
779/// Returns an error if encoding fails.
780pub fn encode_to_canonical<T: CborEncode>(value: &T) -> Result<CanonicalCbor, CborError> {
781    let mut enc = Encoder::new();
782    value.encode(&mut enc)?;
783    enc.into_canonical()
784}
785
786fn mag_to_u128(mag: &[u8]) -> Option<u128> {
787    if mag.len() > 16 {
788        return None;
789    }
790    let mut buf = [0u8; 16];
791    let start = 16 - mag.len();
792    buf[start..].copy_from_slice(mag);
793    Some(u128::from_be_bytes(buf))
794}
795
796impl<'de> CborDecode<'de> for () {
797    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
798        decoder.parse_null()
799    }
800}
801
802#[allow(clippy::use_self)]
803impl<'de> CborDecode<'de> for bool {
804    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
805        decoder.parse_bool()
806    }
807}
808
809impl<'de> CborDecode<'de> for i64 {
810    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
811        decoder.parse_safe_i64()
812    }
813}
814
815impl<'de> CborDecode<'de> for i32 {
816    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
817        let off = decoder.position();
818        let v = decoder.parse_safe_i64()?;
819        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
820    }
821}
822
823impl<'de> CborDecode<'de> for i16 {
824    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
825        let off = decoder.position();
826        let v = decoder.parse_safe_i64()?;
827        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
828    }
829}
830
831impl<'de> CborDecode<'de> for i8 {
832    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
833        let off = decoder.position();
834        let v = decoder.parse_safe_i64()?;
835        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
836    }
837}
838
839impl<'de> CborDecode<'de> for isize {
840    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
841        let off = decoder.position();
842        let v = decoder.parse_safe_i64()?;
843        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
844    }
845}
846
847impl<'de> CborDecode<'de> for i128 {
848    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
849        let (major, ai, off) = decoder.read_header()?;
850        match major {
851            0 => {
852                let v = decoder.read_uint_arg(ai, off)?;
853                if CHECKED && v > MAX_SAFE_INTEGER {
854                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
855                }
856                let v_i = i64::try_from(v)
857                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
858                Ok(Self::from(v_i))
859            }
860            1 => {
861                let n = decoder.read_uint_arg(ai, off)?;
862                if CHECKED && n >= MAX_SAFE_INTEGER {
863                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
864                }
865                let n_i = i64::try_from(n)
866                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
867                Ok(Self::from(-1 - n_i))
868            }
869            6 => {
870                let (negative, mag) = decoder.parse_bignum(off, ai)?;
871                let n = mag_to_u128(mag)
872                    .ok_or_else(|| CborError::new(ErrorCode::ExpectedInteger, off))?;
873                let n_i = Self::try_from(n)
874                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
875                Ok(if negative { -1 - n_i } else { n_i })
876            }
877            _ => Err(CborError::new(ErrorCode::ExpectedInteger, off)),
878        }
879    }
880}
881
882impl<'de> CborDecode<'de> for u64 {
883    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
884        decoder.parse_safe_u64()
885    }
886}
887
888impl<'de> CborDecode<'de> for u32 {
889    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
890        let off = decoder.position();
891        let v = decoder.parse_safe_u64()?;
892        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
893    }
894}
895
896impl<'de> CborDecode<'de> for u16 {
897    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
898        let off = decoder.position();
899        let v = decoder.parse_safe_u64()?;
900        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
901    }
902}
903
904impl<'de> CborDecode<'de> for u8 {
905    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
906        let off = decoder.position();
907        let v = decoder.parse_safe_u64()?;
908        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
909    }
910}
911
912impl<'de> CborDecode<'de> for usize {
913    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
914        let off = decoder.position();
915        let v = decoder.parse_safe_u64()?;
916        Self::try_from(v).map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))
917    }
918}
919
920impl<'de> CborDecode<'de> for u128 {
921    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
922        let (major, ai, off) = decoder.read_header()?;
923        match major {
924            0 => {
925                let v = decoder.read_uint_arg(ai, off)?;
926                if CHECKED && v > MAX_SAFE_INTEGER {
927                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
928                }
929                let v_i = i64::try_from(v)
930                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
931                let v_u64 = u64::try_from(v_i)
932                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
933                Ok(Self::from(v_u64))
934            }
935            6 => {
936                let (negative, mag) = decoder.parse_bignum(off, ai)?;
937                if negative {
938                    return Err(CborError::new(ErrorCode::ExpectedInteger, off));
939                }
940                mag_to_u128(mag).ok_or_else(|| CborError::new(ErrorCode::ExpectedInteger, off))
941            }
942            _ => Err(CborError::new(ErrorCode::ExpectedInteger, off)),
943        }
944    }
945}
946
947#[cfg(feature = "alloc")]
948impl<'de> CborDecode<'de> for BigInt {
949    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
950        let (major, ai, off) = decoder.read_header()?;
951        if major != 6 {
952            return Err(CborError::new(ErrorCode::ExpectedInteger, off));
953        }
954        let (negative, mag) = decoder.parse_bignum(off, ai)?;
955        let magnitude = alloc_util::try_vec_from_slice(mag, off)?;
956        Self::new(negative, magnitude).map_err(|err| CborError::new(err.code, off))
957    }
958}
959
960#[cfg(feature = "alloc")]
961impl<'de> CborDecode<'de> for CborInteger {
962    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
963        let (major, ai, off) = decoder.read_header()?;
964        match major {
965            0 => {
966                let v = decoder.read_uint_arg(ai, off)?;
967                if CHECKED && v > MAX_SAFE_INTEGER {
968                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
969                }
970                let v_i = i64::try_from(v)
971                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
972                Self::safe(v_i).map_err(|err| CborError::new(err.code, off))
973            }
974            1 => {
975                let n = decoder.read_uint_arg(ai, off)?;
976                if CHECKED && n >= MAX_SAFE_INTEGER {
977                    return Err(CborError::new(ErrorCode::IntegerOutsideSafeRange, off));
978                }
979                let n_i = i64::try_from(n)
980                    .map_err(|_| CborError::new(ErrorCode::ExpectedInteger, off))?;
981                Self::safe(-1 - n_i).map_err(|err| CborError::new(err.code, off))
982            }
983            6 => {
984                let (negative, mag) = decoder.parse_bignum(off, ai)?;
985                let magnitude = alloc_util::try_vec_from_slice(mag, off)?;
986                Self::big(negative, magnitude).map_err(|err| CborError::new(err.code, off))
987            }
988            _ => Err(CborError::new(ErrorCode::ExpectedInteger, off)),
989        }
990    }
991}
992
993impl<'de> CborDecode<'de> for f64 {
994    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
995        decoder.parse_float64()
996    }
997}
998
999impl<'de> CborDecode<'de> for f32 {
1000    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1001        let off = decoder.position();
1002        let v = decoder.parse_float64()?;
1003        if v.is_nan() {
1004            return Ok(Self::NAN);
1005        }
1006        let bits = v.to_bits();
1007        let sign = ((bits >> 63) as u32) << 31;
1008        let exp = ((bits >> 52) & 0x7ff) as i32;
1009        let mant = bits & 0x000f_ffff_ffff_ffff;
1010        if exp == 0x7ff {
1011            if mant != 0 {
1012                return Ok(Self::NAN);
1013            }
1014            return Ok(Self::from_bits(sign | 0x7f80_0000));
1015        }
1016        if exp == 0 {
1017            if mant == 0 {
1018                return Ok(Self::from_bits(sign));
1019            }
1020            return Err(CborError::new(ErrorCode::ExpectedFloat, off));
1021        }
1022
1023        let e = exp - 1023;
1024        let mant_with_hidden = (1u64 << 52) | mant;
1025        if e > 127 {
1026            return Err(CborError::new(ErrorCode::ExpectedFloat, off));
1027        }
1028        if e >= -126 {
1029            let lower = mant_with_hidden & ((1u64 << 29) - 1);
1030            if lower != 0 {
1031                return Err(CborError::new(ErrorCode::ExpectedFloat, off));
1032            }
1033            let mant32 = u32::try_from(mant_with_hidden >> 29)
1034                .map_err(|_| CborError::new(ErrorCode::ExpectedFloat, off))?
1035                & 0x7f_ffff;
1036            let exp32 = u32::try_from(e + 127)
1037                .map_err(|_| CborError::new(ErrorCode::ExpectedFloat, off))?;
1038            return Ok(Self::from_bits(sign | (exp32 << 23) | mant32));
1039        }
1040        if e >= -149 {
1041            let shift = u32::try_from(-e - 97)
1042                .map_err(|_| CborError::new(ErrorCode::ExpectedFloat, off))?;
1043            let lower = mant_with_hidden & ((1u64 << shift) - 1);
1044            if lower != 0 {
1045                return Err(CborError::new(ErrorCode::ExpectedFloat, off));
1046            }
1047            let mant32 = u32::try_from(mant_with_hidden >> shift)
1048                .map_err(|_| CborError::new(ErrorCode::ExpectedFloat, off))?;
1049            if mant32 == 0 || mant32 > 0x7f_ffff {
1050                return Err(CborError::new(ErrorCode::ExpectedFloat, off));
1051            }
1052            return Ok(Self::from_bits(sign | mant32));
1053        }
1054        Err(CborError::new(ErrorCode::ExpectedFloat, off))
1055    }
1056}
1057
1058impl<'de> CborDecode<'de> for &'de str {
1059    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1060        decoder.parse_text()
1061    }
1062}
1063
1064impl<'de> CborDecode<'de> for &'de [u8] {
1065    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1066        decoder.parse_bytes()
1067    }
1068}
1069
1070impl<'de> CborDecode<'de> for CborValueRef<'de> {
1071    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1072        let start = decoder.position();
1073        decoder.skip_value()?;
1074        let end = decoder.position();
1075        Ok(CborValueRef::new(decoder.data(), start, end))
1076    }
1077}
1078
1079impl<'de, T: CborDecode<'de>> CborDecode<'de> for Option<T> {
1080    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1081        if decoder.peek_u8()? == 0xf6 {
1082            decoder.parse_null()?;
1083            Ok(None)
1084        } else {
1085            T::decode(decoder).map(Some)
1086        }
1087    }
1088}
1089
1090#[cfg(feature = "alloc")]
1091impl<'de, T: CborDecode<'de> + CborArrayElem> CborDecode<'de> for Vec<T> {
1092    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1093        let off = decoder.position();
1094        let mut array = decoder.array()?;
1095        let mut out = alloc_util::try_vec_with_capacity::<T>(array.remaining(), off)?;
1096        while let Some(item) = array.next_value()? {
1097            out.push(item);
1098        }
1099        Ok(out)
1100    }
1101}
1102
1103#[cfg(feature = "alloc")]
1104impl<'de, V: CborDecode<'de>> CborDecode<'de> for BTreeMap<String, V> {
1105    /// Decode a CBOR map into a `BTreeMap<String, V>`.
1106    ///
1107    /// # Canonical requirements
1108    ///
1109    /// Inputs must still be canonical SACP-CBOR/1. This impl does not relax the profile.
1110    ///
1111    /// # OOM note
1112    ///
1113    /// Key copying uses fallible allocation helpers and can return `AllocationFailed`. However,
1114    /// `BTreeMap` insertion may allocate internally using infallible APIs; in a real OOM situation
1115    /// the process may abort rather than returning `AllocationFailed`.
1116    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1117        let off = decoder.position();
1118        let mut map = decoder.map()?;
1119        let mut out = Self::new();
1120        while let Some(key) = map.next_key()? {
1121            let value: V = map.next_value()?;
1122            let owned = alloc_util::try_string_from_str(key, off)?;
1123            if out.insert(owned, value).is_some() {
1124                return Err(CborError::new(ErrorCode::DuplicateMapKey, off));
1125            }
1126        }
1127        Ok(out)
1128    }
1129}
1130
1131#[cfg(feature = "std")]
1132impl<'de, V: CborDecode<'de>, S: BuildHasher + Default> CborDecode<'de> for HashMap<String, V, S> {
1133    /// Decode a CBOR map into a `HashMap<String, V, S>`.
1134    ///
1135    /// # Canonical requirements
1136    ///
1137    /// Inputs must still be canonical SACP-CBOR/1. This impl does not relax the profile.
1138    ///
1139    /// # OOM note
1140    ///
1141    /// Key copying uses fallible allocation helpers and can return `AllocationFailed`. However,
1142    /// `HashMap` insertion may allocate internally using infallible APIs; in a real OOM situation
1143    /// the process may abort rather than returning `AllocationFailed`.
1144    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1145        let off = decoder.position();
1146        let mut map = decoder.map()?;
1147        let mut out = Self::with_capacity_and_hasher(map.remaining(), S::default());
1148        while let Some(key) = map.next_key()? {
1149            let value: V = map.next_value()?;
1150            let owned = alloc_util::try_string_from_str(key, off)?;
1151            if out.insert(owned, value).is_some() {
1152                return Err(CborError::new(ErrorCode::DuplicateMapKey, off));
1153            }
1154        }
1155        Ok(out)
1156    }
1157}
1158
1159#[cfg(feature = "alloc")]
1160impl<'de, V: CborDecode<'de>> CborDecode<'de> for MapEntries<&'de str, V> {
1161    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1162        let off = decoder.position();
1163        let mut map = decoder.map()?;
1164        let mut out = alloc_util::try_vec_with_capacity::<(&'de str, V)>(map.remaining(), off)?;
1165        while let Some((key, value)) = map.next_entry()? {
1166            out.push((key, value));
1167        }
1168        Ok(Self(out))
1169    }
1170}
1171
1172#[cfg(feature = "alloc")]
1173impl<'de, V: CborDecode<'de>> CborDecode<'de> for MapEntries<String, V> {
1174    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1175        let off = decoder.position();
1176        let mut map = decoder.map()?;
1177        let mut out = alloc_util::try_vec_with_capacity::<(String, V)>(map.remaining(), off)?;
1178        while let Some(key) = map.next_key()? {
1179            let value = map.next_value()?;
1180            let owned = alloc_util::try_string_from_str(key, off)?;
1181            out.push((owned, value));
1182        }
1183        Ok(Self(out))
1184    }
1185}
1186
1187#[cfg(feature = "alloc")]
1188impl<'de> CborDecode<'de> for String {
1189    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1190        let off = decoder.position();
1191        let s = decoder.parse_text()?;
1192        alloc_util::try_string_from_str(s, off)
1193    }
1194}
1195
1196#[cfg(feature = "alloc")]
1197impl<'de> CborDecode<'de> for Vec<u8> {
1198    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1199        let off = decoder.position();
1200        let bytes = decoder.parse_bytes()?;
1201        alloc_util::try_vec_u8_from_slice(bytes, off)
1202    }
1203}
1204
1205impl<'de, const N: usize> CborDecode<'de> for [u8; N] {
1206    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1207        let off = decoder.position();
1208        let bytes = decoder.parse_bytes()?;
1209        if bytes.len() != N {
1210            return Err(CborError::new(ErrorCode::ExpectedBytes, off));
1211        }
1212        let mut out = [0u8; N];
1213        out.copy_from_slice(bytes);
1214        Ok(out)
1215    }
1216}
1217
1218impl<'de> CborDecode<'de> for CanonicalCborRef<'de> {
1219    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1220        let start = decoder.position();
1221        decoder.skip_value()?;
1222        let end = decoder.position();
1223        Ok(CanonicalCborRef::new(&decoder.data()[start..end]))
1224    }
1225}
1226
1227#[cfg(feature = "alloc")]
1228impl<'de> CborDecode<'de> for CanonicalCbor {
1229    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1230        let off = decoder.position();
1231        let canon_ref = CanonicalCborRef::decode(decoder)?;
1232        let bytes = alloc_util::try_vec_from_slice(canon_ref.as_bytes(), off)?;
1233        Ok(Self::new_unchecked(bytes))
1234    }
1235}
1236
1237#[cfg(feature = "alloc")]
1238impl<'de, T> CborDecode<'de> for BTreeSet<T>
1239where
1240    T: CborDecode<'de> + CborArrayElem + Ord,
1241{
1242    fn decode<const CHECKED: bool>(decoder: &mut Decoder<'de, CHECKED>) -> Result<Self, CborError> {
1243        let off = decoder.position();
1244        let mut array = decoder.array()?;
1245        let mut out = Self::new();
1246        while let Some(value) = array.next_value::<T>()? {
1247            if let Some(last) = out.last() {
1248                if value.cmp(last) != core::cmp::Ordering::Greater {
1249                    return Err(CborError::new(ErrorCode::NonCanonicalSetOrder, off));
1250                }
1251            }
1252            out.insert(value);
1253        }
1254        Ok(out)
1255    }
1256}
1257
1258#[cfg(feature = "alloc")]
1259impl CborEncode for () {
1260    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1261        enc.null()
1262    }
1263}
1264
1265#[cfg(feature = "alloc")]
1266impl CborEncode for bool {
1267    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1268        enc.bool(*self)
1269    }
1270}
1271
1272#[cfg(feature = "alloc")]
1273impl CborEncode for i64 {
1274    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1275        enc.int(*self)
1276    }
1277}
1278
1279#[cfg(feature = "alloc")]
1280impl CborEncode for i32 {
1281    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1282        enc.int(i64::from(*self))
1283    }
1284}
1285
1286#[cfg(feature = "alloc")]
1287impl CborEncode for i16 {
1288    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1289        enc.int(i64::from(*self))
1290    }
1291}
1292
1293#[cfg(feature = "alloc")]
1294impl CborEncode for i8 {
1295    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1296        enc.int(i64::from(*self))
1297    }
1298}
1299
1300#[cfg(feature = "alloc")]
1301impl CborEncode for isize {
1302    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1303        enc.int(
1304            i64::try_from(*self)
1305                .map_err(|_| CborError::new(ErrorCode::LengthOverflow, enc.len()))?,
1306        )
1307    }
1308}
1309
1310#[cfg(feature = "alloc")]
1311impl CborEncode for i128 {
1312    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1313        enc.int_i128(*self)
1314    }
1315}
1316
1317#[cfg(feature = "alloc")]
1318impl CborEncode for u64 {
1319    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1320        if *self > crate::MAX_SAFE_INTEGER {
1321            return Err(CborError::new(
1322                ErrorCode::IntegerOutsideSafeRange,
1323                enc.len(),
1324            ));
1325        }
1326        let v = i64::try_from(*self)
1327            .map_err(|_| CborError::new(ErrorCode::LengthOverflow, enc.len()))?;
1328        enc.int(v)
1329    }
1330}
1331
1332#[cfg(feature = "alloc")]
1333impl CborEncode for u32 {
1334    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1335        enc.int(i64::from(*self))
1336    }
1337}
1338
1339#[cfg(feature = "alloc")]
1340impl CborEncode for u16 {
1341    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1342        enc.int(i64::from(*self))
1343    }
1344}
1345
1346#[cfg(feature = "alloc")]
1347impl CborEncode for u8 {
1348    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1349        enc.int(i64::from(*self))
1350    }
1351}
1352
1353#[cfg(feature = "alloc")]
1354impl CborEncode for usize {
1355    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1356        let v = u64::try_from(*self)
1357            .map_err(|_| CborError::new(ErrorCode::LengthOverflow, enc.len()))?;
1358        if v > crate::MAX_SAFE_INTEGER {
1359            return Err(CborError::new(
1360                ErrorCode::IntegerOutsideSafeRange,
1361                enc.len(),
1362            ));
1363        }
1364        let v =
1365            i64::try_from(v).map_err(|_| CborError::new(ErrorCode::LengthOverflow, enc.len()))?;
1366        enc.int(v)
1367    }
1368}
1369
1370#[cfg(feature = "alloc")]
1371impl CborEncode for u128 {
1372    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1373        enc.int_u128(*self)
1374    }
1375}
1376
1377#[cfg(feature = "alloc")]
1378impl CborEncode for BigInt {
1379    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1380        enc.bignum(self.is_negative(), self.magnitude())
1381    }
1382}
1383
1384#[cfg(feature = "alloc")]
1385impl CborEncode for CborInteger {
1386    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1387        if let Some(value) = self.as_i64() {
1388            enc.int(value)
1389        } else if let Some(big) = self.as_bigint() {
1390            enc.bignum(big.is_negative(), big.magnitude())
1391        } else {
1392            Err(CborError::new(ErrorCode::ExpectedInteger, enc.len()))
1393        }
1394    }
1395}
1396
1397#[cfg(feature = "alloc")]
1398impl CborEncode for f64 {
1399    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1400        let bits = crate::scalar::F64Bits::try_from_f64(*self)?;
1401        enc.float(bits)
1402    }
1403}
1404
1405#[cfg(feature = "alloc")]
1406impl CborEncode for f32 {
1407    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1408        let bits = crate::scalar::F64Bits::try_from_f64(f64::from(*self))?;
1409        enc.float(bits)
1410    }
1411}
1412
1413#[cfg(feature = "alloc")]
1414impl CborEncode for &str {
1415    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1416        enc.text(self)
1417    }
1418}
1419
1420#[cfg(feature = "alloc")]
1421impl CborEncode for &[u8] {
1422    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1423        enc.bytes(self)
1424    }
1425}
1426
1427#[cfg(feature = "alloc")]
1428impl CborEncode for String {
1429    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1430        enc.text(self)
1431    }
1432}
1433
1434#[cfg(feature = "alloc")]
1435impl CborEncode for Vec<u8> {
1436    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1437        enc.bytes(self)
1438    }
1439}
1440
1441#[cfg(feature = "alloc")]
1442impl<const N: usize> CborEncode for [u8; N] {
1443    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1444        enc.bytes(self)
1445    }
1446}
1447
1448#[cfg(feature = "alloc")]
1449impl CborEncode for CborValueRef<'_> {
1450    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1451        enc.raw_value_ref(*self)
1452    }
1453}
1454
1455#[cfg(feature = "alloc")]
1456impl CborEncode for CanonicalCborRef<'_> {
1457    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1458        enc.raw_cbor(*self)
1459    }
1460}
1461
1462#[cfg(feature = "alloc")]
1463impl CborEncode for CanonicalCbor {
1464    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1465        enc.raw_cbor(self.as_ref())
1466    }
1467}
1468
1469#[cfg(feature = "alloc")]
1470impl<T: CborEncode> CborEncode for Option<T> {
1471    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1472        match self {
1473            Some(v) => v.encode(enc),
1474            None => enc.null(),
1475        }
1476    }
1477}
1478
1479#[cfg(feature = "alloc")]
1480impl<T: CborEncode + CborArrayElem> CborEncode for Vec<T> {
1481    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1482        enc.array(self.len(), |a| {
1483            for item in self {
1484                a.value(item)?;
1485            }
1486            Ok(())
1487        })
1488    }
1489}
1490
1491#[cfg(feature = "alloc")]
1492impl<K, V> CborEncode for BTreeMap<K, V>
1493where
1494    K: AsRef<str> + Ord,
1495    V: CborEncode,
1496{
1497    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1498        let off = enc.len();
1499        let mut entries = alloc_util::try_vec_with_capacity::<(&str, &V)>(self.len(), off)?;
1500        for (k, v) in self {
1501            entries.push((k.as_ref(), v));
1502        }
1503        entries.sort_by(|(a, _), (b, _)| crate::profile::cmp_text_keys_canonical(a, b));
1504
1505        enc.map(entries.len(), |m| {
1506            for (k, v) in entries {
1507                m.entry(k, |enc| v.encode(enc))?;
1508            }
1509            Ok(())
1510        })
1511    }
1512}
1513
1514#[cfg(feature = "std")]
1515impl<K, V, S> CborEncode for HashMap<K, V, S>
1516where
1517    K: AsRef<str> + Eq + core::hash::Hash,
1518    V: CborEncode,
1519    S: BuildHasher,
1520{
1521    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1522        let off = enc.len();
1523        let mut entries = alloc_util::try_vec_with_capacity::<(&str, &V)>(self.len(), off)?;
1524        for (k, v) in self {
1525            entries.push((k.as_ref(), v));
1526        }
1527        entries.sort_by(|(a, _), (b, _)| crate::profile::cmp_text_keys_canonical(a, b));
1528
1529        enc.map(entries.len(), |m| {
1530            for (k, v) in entries {
1531                m.entry(k, |enc| v.encode(enc))?;
1532            }
1533            Ok(())
1534        })
1535    }
1536}
1537
1538#[cfg(feature = "alloc")]
1539impl<K, V> CborEncode for MapEntries<K, V>
1540where
1541    K: AsRef<str>,
1542    V: CborEncode,
1543{
1544    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1545        enc.map(self.0.len(), |m| {
1546            for (k, v) in &self.0 {
1547                m.entry(k.as_ref(), |enc| v.encode(enc))?;
1548            }
1549            Ok(())
1550        })
1551    }
1552}
1553
1554#[cfg(feature = "alloc")]
1555impl<T> CborEncode for BTreeSet<T>
1556where
1557    T: CborEncode + CborArrayElem + Ord,
1558{
1559    fn encode(&self, enc: &mut Encoder) -> Result<(), CborError> {
1560        enc.array(self.len(), |a| {
1561            for item in self {
1562                a.value(item)?;
1563            }
1564            Ok(())
1565        })
1566    }
1567}
1568
1569#[cfg(feature = "alloc")]
1570impl CborArrayElem for bool {}
1571#[cfg(feature = "alloc")]
1572impl CborArrayElem for i64 {}
1573#[cfg(feature = "alloc")]
1574impl CborArrayElem for i32 {}
1575#[cfg(feature = "alloc")]
1576impl CborArrayElem for i16 {}
1577#[cfg(feature = "alloc")]
1578impl CborArrayElem for i8 {}
1579#[cfg(feature = "alloc")]
1580impl CborArrayElem for isize {}
1581#[cfg(feature = "alloc")]
1582impl CborArrayElem for i128 {}
1583#[cfg(feature = "alloc")]
1584impl CborArrayElem for u64 {}
1585#[cfg(feature = "alloc")]
1586impl CborArrayElem for u32 {}
1587#[cfg(feature = "alloc")]
1588impl CborArrayElem for u16 {}
1589#[cfg(feature = "alloc")]
1590impl CborArrayElem for usize {}
1591#[cfg(feature = "alloc")]
1592impl CborArrayElem for u128 {}
1593#[cfg(feature = "alloc")]
1594impl CborArrayElem for f64 {}
1595#[cfg(feature = "alloc")]
1596impl CborArrayElem for f32 {}
1597#[cfg(feature = "alloc")]
1598impl CborArrayElem for String {}
1599#[cfg(feature = "alloc")]
1600impl CborArrayElem for &str {}
1601#[cfg(feature = "alloc")]
1602impl CborArrayElem for &[u8] {}
1603#[cfg(feature = "alloc")]
1604impl<const N: usize> CborArrayElem for [u8; N] {}
1605#[cfg(feature = "alloc")]
1606impl CborArrayElem for BigInt {}
1607#[cfg(feature = "alloc")]
1608impl CborArrayElem for CborInteger {}
1609#[cfg(feature = "alloc")]
1610impl CborArrayElem for CborValueRef<'_> {}
1611#[cfg(feature = "alloc")]
1612impl CborArrayElem for CanonicalCborRef<'_> {}
1613#[cfg(feature = "alloc")]
1614impl CborArrayElem for CanonicalCbor {}
1615#[cfg(feature = "alloc")]
1616impl<T: CborArrayElem> CborArrayElem for Option<T> {}
1617#[cfg(feature = "alloc")]
1618impl<T: CborArrayElem> CborArrayElem for Vec<T> {}
1619#[cfg(feature = "alloc")]
1620impl<K, V> CborArrayElem for MapEntries<K, V>
1621where
1622    K: AsRef<str>,
1623    V: CborArrayElem,
1624{
1625}
1626
1627#[cfg(feature = "alloc")]
1628impl<K, V> CborArrayElem for BTreeMap<K, V>
1629where
1630    K: AsRef<str> + Ord,
1631    V: CborArrayElem,
1632{
1633}
1634
1635#[cfg(feature = "alloc")]
1636impl<T> CborArrayElem for BTreeSet<T> where T: CborArrayElem + Ord {}
1637
1638#[cfg(feature = "std")]
1639impl<K, V, S> CborArrayElem for HashMap<K, V, S>
1640where
1641    K: AsRef<str> + Eq + core::hash::Hash,
1642    V: CborArrayElem,
1643    S: BuildHasher,
1644{
1645}