Skip to main content

darkbio_crypto/cbor/
mod.rs

1// crypto-rs: cryptography primitives and wrappers
2// Copyright 2025 Dark Bio AG. All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7//! Tiny, security-focused CBOR encoder/decoder.
8//!
9//! <https://datatracker.ietf.org/doc/html/rfc8949>
10//!
11//! # Type system
12//!
13//! Only a minimal subset of CBOR is supported:
14//!
15//! - **Booleans:** `bool`
16//! - **Integers:** `u64`, `i64`
17//! - **Text:**     `String`, `&str`
18//! - **Bytes:**    `Vec<u8>`, `&[u8]`, `[u8; N]`
19//! - **Null:**     `Option<T>::None`, [`Null`]
20//! - **Arrays:**   `()`, `(X,)`, `(X, Y)`, ... tuples, [`Array<T>`], [`FixedArray<T, N>`], or structs with `#[cbor(array)]`
21//! - **Maps:**     structs with `#[cbor(key = N)]` fields (integer keys, deterministic order)
22//! - **Raw:**      [`Raw`] (opaque CBOR bytes, passed through without parsing)
23//!
24//! # Values
25//!
26//! Built in types and tuples go through [`encode`] and [`decode`] directly, and
27//! decoding a whole blob rejects trailing bytes.
28//!
29//! ```
30//! use darkbio_crypto::cbor;
31//!
32//! let bytes = cbor::encode(&(1u64, "two", vec![3u8])).unwrap();
33//! assert_eq!(bytes, [0x83, 0x01, 0x63, 0x74, 0x77, 0x6f, 0x41, 0x03]);
34//!
35//! let (a, b, c): (u64, String, Vec<u8>) = cbor::decode(&bytes).unwrap();
36//! assert_eq!((a, b, c), (1, "two".to_string(), vec![3]));
37//! ```
38//!
39//! # Derive macros
40//!
41//! Array mode, fields encode positionally:
42//!
43//! ```
44//! use darkbio_crypto::cbor::{self, Cbor};
45//!
46//! #[derive(Cbor, Debug, PartialEq)]
47//! #[cbor(array)]
48//! struct Foo {
49//!     a: u64,
50//!     b: String,
51//! }
52//!
53//! let foo = Foo { a: 1, b: "x".into() };
54//! let bytes = cbor::encode(&foo).unwrap();
55//! assert_eq!(bytes, [0x82, 0x01, 0x61, 0x78]);
56//! assert_eq!(cbor::decode::<Foo>(&bytes).unwrap(), foo);
57//! ```
58//!
59//! Map mode, fields encode as key-value pairs sorted by CBOR key bytes:
60//!
61//! ```
62//! use darkbio_crypto::cbor::{self, Cbor};
63//!
64//! #[derive(Cbor, Debug, PartialEq)]
65//! struct Bar {
66//!     #[cbor(key = 1)]
67//!     x: u64,                 // required
68//!     #[cbor(key = 2)]
69//!     y: Option<Vec<u8>>,     // optional, omitted when None
70//!     #[cbor(key = 3)]
71//!     z: Option<Option<u64>>, // nullable, always present as a value or null
72//! }
73//!
74//! let bar = Bar { x: 7, y: None, z: Some(None) };
75//! let bytes = cbor::encode(&bar).unwrap();
76//! assert_eq!(bytes, [0xa2, 0x01, 0x07, 0x03, 0xf6]);
77//! assert_eq!(cbor::decode::<Bar>(&bytes).unwrap(), bar);
78//! ```
79//!
80//! # Embedding
81//!
82//! Fields marked `#[cbor(embed)]` are flattened into the parent map. The embedded
83//! type must itself be a map-mode struct. Keys across all embeds and direct fields
84//! must not overlap.
85//!
86//! ```
87//! use darkbio_crypto::cbor::{self, Cbor};
88//!
89//! #[derive(Cbor, Debug, PartialEq)]
90//! struct Inner {
91//!     #[cbor(key = 1)]
92//!     a: u64,
93//!     #[cbor(key = 2)]
94//!     b: u64,
95//! }
96//!
97//! #[derive(Cbor, Debug, PartialEq)]
98//! struct Outer {
99//!     #[cbor(embed)]
100//!     inner: Inner, // keys from Inner merge into Outer
101//!     #[cbor(key = 3)]
102//!     c: u64,
103//! }
104//!
105//! let outer = Outer { inner: Inner { a: 1, b: 2 }, c: 3 };
106//! let bytes = cbor::encode(&outer).unwrap();
107//! assert_eq!(bytes, [0xa3, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03]);
108//! assert_eq!(cbor::decode::<Outer>(&bytes).unwrap(), outer);
109//! ```
110//!
111//! Optional embeds (`Option<T>`) use all-or-none semantics. Either every required
112//! key from the embedded struct is present (`Some`), or none are (`None`). Partial
113//! presence is rejected.
114//!
115//! ```
116//! use darkbio_crypto::cbor::{self, Cbor};
117//!
118//! #[derive(Cbor, Debug, PartialEq)]
119//! struct Extra {
120//!     #[cbor(key = 1)]
121//!     a: u64,
122//!     #[cbor(key = 2)]
123//!     b: u64,
124//! }
125//!
126//! #[derive(Cbor, Debug, PartialEq)]
127//! struct Outer {
128//!     #[cbor(embed)]
129//!     extra: Option<Extra>, // all Extra keys present, or none
130//!     #[cbor(key = 3)]
131//!     c: u64,
132//! }
133//!
134//! let bytes = cbor::encode(&Outer { extra: None, c: 3 }).unwrap();
135//! assert_eq!(bytes, [0xa1, 0x03, 0x03]);
136//!
137//! let partial = [0xa2, 0x01, 0x01, 0x03, 0x03]; // only one of Extra's keys
138//! assert!(cbor::decode::<Outer>(&partial).is_err());
139//! ```
140//!
141//! # Encoding rules
142//!
143//! Built-in types and derived structs use deterministic encoding (RFC 8949
144//! Section 4.2.1): shortest-form integers, map keys sorted by encoded bytes, no
145//! indefinite lengths, no floats, and no tags. Their decoders enforce these
146//! rules for the values they decode and reject unknown struct fields.
147//!
148//! [`Raw`] is an exception. Encoding copies its bytes without validation, and
149//! decoding only walks enough structure to find an item's boundaries. A raw
150//! item can contain duplicate or unsorted map keys, non-integer map keys, or
151//! invalid UTF-8. Use [`verify`] to validate the complete CBOR item, including
152//! any raw fields, when the deterministic encoding rules are required. Custom
153//! [`Encode`] and [`Decode`] implementations are responsible for their own
154//! validation too.
155
156pub use darkbio_crypto_cbor_derive::Cbor;
157
158use std::cmp::Ordering;
159
160// Supported CBOR major types
161const MAJOR_UINT: u8 = 0;
162const MAJOR_NINT: u8 = 1;
163const MAJOR_BYTES: u8 = 2;
164const MAJOR_TEXT: u8 = 3;
165const MAJOR_ARRAY: u8 = 4;
166const MAJOR_MAP: u8 = 5;
167const MAJOR_SIMPLE: u8 = 7;
168
169// Additional info values
170const INFO_UINT8: u8 = 24;
171const INFO_UINT16: u8 = 25;
172const INFO_UINT32: u8 = 26;
173const INFO_UINT64: u8 = 27;
174
175// Simple values (major type 7)
176const SIMPLE_FALSE: u8 = 20;
177const SIMPLE_TRUE: u8 = 21;
178const SIMPLE_NULL: u8 = 22;
179
180/// Maximum nesting depth for CBOR arrays and maps. Inputs nested deeper than
181/// this are rejected to prevent stack overflow from recursive parsing.
182const MAX_DEPTH: usize = 32;
183
184/// Failures of encoding and decoding CBOR data.
185#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
186pub enum Error {
187    /// The next item has the first major type where the second was expected.
188    #[error("invalid major type: {0}, want {1}")]
189    InvalidMajorType(u8, u8),
190    /// The additional info bits name an encoding outside the supported
191    /// subset, indefinite lengths or reserved values.
192    #[error("invalid additional info: {0}")]
193    InvalidAdditionalInfo(u8),
194    /// The data ended inside an item.
195    #[error("unexpected end of data")]
196    UnexpectedEof,
197    /// An integer or length is not in its shortest form.
198    #[error("non-canonical encoding")]
199    NonCanonical,
200    /// A text string is not valid UTF-8. Raised by [`Decoder::decode_text`] and
201    /// [`verify`].
202    #[error("invalid UTF-8 in text string")]
203    InvalidUtf8,
204    /// Bytes follow the decoded item. [`decode`] and [`verify`] reject them.
205    #[error("unexpected trailing bytes")]
206    TrailingBytes,
207    /// An array or byte string has the first length where the target type
208    /// needs the second.
209    #[error("unexpected item count: {0}, want {1}")]
210    UnexpectedItemCount(u64, usize),
211    /// The major type is outside the supported subset, tags, floats or simple
212    /// values other than booleans and null. Raised by [`verify`] and when a
213    /// [`Raw`] item is skipped over.
214    #[error("unsupported type: {0}")]
215    UnsupportedType(u8),
216    /// An integer does not fit the target type. The flag marks a negative
217    /// value, followed by the wire value and the largest one allowed. Raised
218    /// by [`Decoder::decode_int`].
219    #[error("{sign} integer overflow: {value} exceeds max {max}", sign = if *.0 { "negative" } else { "positive" }, value = .1, max = .2)]
220    IntegerOverflow(bool, u64, u64),
221    /// A map carries the key twice, on decoding or when
222    /// [`MapEncodeBuffer::finish_to`] assembles one.
223    #[error("duplicate map key: {0}")]
224    DuplicateMapKey(i64),
225    /// Map keys are out of deterministic order. The first key was read after
226    /// the second but sorts before it.
227    #[error("invalid map key order: {0} must come before {1}")]
228    InvalidMapKeyOrder(i64, i64),
229    /// Arrays or maps nest deeper than the limit. Raised by [`verify`] and when
230    /// a [`Raw`] item is skipped over.
231    #[error("nesting depth exceeds maximum of {0}")]
232    MaxDepthExceeded(usize),
233    /// A type's own validation rejected the decoded value, a key of the wrong
234    /// size, an unknown map key or a missing required one. The message names
235    /// the problem.
236    #[error("decode failed: {0}")]
237    DecodeFailed(String),
238}
239
240/// Encodes a generic Rust value to CBOR, using the tiny, strict subset of types
241/// permitted by this package.
242///
243/// Validation depends on the value's [`Encode`] implementation. In particular,
244/// [`Raw`] copies bytes verbatim; use [`verify`] to check the resulting encoding.
245pub fn encode<T: Encode>(value: T) -> Result<Vec<u8>, Error> {
246    let mut buf = Vec::with_capacity(128);
247    value.encode_cbor_to(&mut buf)?;
248    Ok(buf)
249}
250
251/// Decodes a CBOR blob into a generic Rust type, using the tiny, strict subset
252/// of types permitted by this package.
253///
254/// Validation depends on the target's [`Decode`] implementation. [`Raw`] fields
255/// are only structurally traversed; use [`verify`] first to validate their contents.
256pub fn decode<T: Decode>(data: &[u8]) -> Result<T, Error> {
257    T::decode_cbor(data)
258}
259
260/// Does a dry-run decoding to verify that only the tiny, strict subset of
261/// types permitted by this package were used.
262///
263/// Checks exactly one complete item, including UTF-8 text, deterministic integer
264/// and length encodings, integer map keys in order without duplicates, and the
265/// nesting limit. It does not validate application-specific schemas or values.
266pub fn verify(data: &[u8]) -> Result<(), Error> {
267    let mut decoder = Decoder::new(data);
268    verify_object(&mut decoder, MAX_DEPTH)?;
269    decoder.finish()
270}
271
272/// The low level implementation of the CBOR encoder with only the
273/// handful of desired types supported.
274pub struct Encoder {
275    buf: Vec<u8>,
276}
277
278impl Encoder {
279    /// Creates a CBOR encoder with an underlying buffer, pre-allocated to
280    /// 1KB (small enough not to be relevant, large enough to avoid tiny appends).
281    pub fn new() -> Self {
282        Self {
283            buf: Vec::with_capacity(1024),
284        }
285    }
286
287    /// Terminates encoding and retrieves the accumulated CBOR data.
288    pub fn finish(self) -> Vec<u8> {
289        self.buf
290    }
291
292    /// Appends raw bytes to the encoder buffer (for derive macros).
293    pub fn extend(&mut self, bytes: &[u8]) {
294        self.buf.extend_from_slice(bytes);
295    }
296
297    /// Encodes a positive integer into its canonical shortest-form.
298    pub fn encode_uint(&mut self, value: u64) {
299        self.encode_length(MAJOR_UINT, value);
300    }
301
302    /// Encodes a signed integer into its canonical shortest-form.
303    pub fn encode_int(&mut self, value: i64) {
304        if value >= 0 {
305            self.encode_length(MAJOR_UINT, value as u64);
306        } else {
307            self.encode_length(MAJOR_NINT, (-1 - value) as u64);
308        }
309    }
310
311    /// Encodes an opaque byte string.
312    pub fn encode_bytes(&mut self, value: &[u8]) {
313        self.encode_length(MAJOR_BYTES, value.len() as u64);
314        self.buf.extend_from_slice(value);
315    }
316
317    /// Encodes a UTF-8 text string.
318    pub fn encode_text(&mut self, value: &str) {
319        self.encode_length(MAJOR_TEXT, value.len() as u64);
320        self.buf.extend_from_slice(value.as_bytes());
321    }
322
323    /// Encodes an array size.
324    pub fn encode_array_header(&mut self, len: usize) {
325        self.encode_length(MAJOR_ARRAY, len as u64);
326    }
327
328    /// Special cases the empty tuple to encode as [].
329    pub fn encode_empty_tuple(&mut self) {
330        self.encode_array_header(0);
331    }
332
333    /// Encodes a map size.
334    pub fn encode_map_header(&mut self, len: usize) {
335        self.encode_length(MAJOR_MAP, len as u64);
336    }
337
338    /// Encodes a CBOR boolean value.
339    pub fn encode_bool(&mut self, value: bool) {
340        self.buf
341            .push(MAJOR_SIMPLE << 5 | if value { SIMPLE_TRUE } else { SIMPLE_FALSE });
342    }
343
344    /// Encodes a CBOR null value.
345    pub fn encode_null(&mut self) {
346        self.buf.push(MAJOR_SIMPLE << 5 | SIMPLE_NULL);
347    }
348
349    /// Encodes a value directly into this encoder's buffer.
350    pub fn encode_field<T: Encode + ?Sized>(&mut self, value: &T) -> Result<(), Error> {
351        value.encode_cbor_to(&mut self.buf)
352    }
353
354    /// Encodes a major type with an unsigned integer, which defines
355    /// the length for most types, or the value itself for integers.
356    fn encode_length(&mut self, major_type: u8, len: u64) {
357        encode_length_to(&mut self.buf, major_type, len);
358    }
359}
360
361impl Default for Encoder {
362    fn default() -> Self {
363        Self::new()
364    }
365}
366
367/// Writes a CBOR major-type + length header directly into a
368/// buffer, matching the canonical shortest-form encoding.
369fn encode_length_to(buf: &mut Vec<u8>, major_type: u8, len: u64) {
370    if len < 24 {
371        buf.push(major_type << 5 | len as u8);
372    } else if len <= u8::MAX as u64 {
373        buf.push(major_type << 5 | INFO_UINT8);
374        buf.push(len as u8);
375    } else if len <= u16::MAX as u64 {
376        buf.push(major_type << 5 | INFO_UINT16);
377        buf.extend_from_slice(&(len as u16).to_be_bytes());
378    } else if len <= u32::MAX as u64 {
379        buf.push(major_type << 5 | INFO_UINT32);
380        buf.extend_from_slice(&(len as u32).to_be_bytes());
381    } else {
382        buf.push(major_type << 5 | INFO_UINT64);
383        buf.extend_from_slice(&len.to_be_bytes());
384    }
385}
386
387/// Encodes a signed integer directly into a buffer.
388pub fn encode_int_to(buf: &mut Vec<u8>, value: i64) {
389    if value >= 0 {
390        encode_length_to(buf, MAJOR_UINT, value as u64);
391    } else {
392        encode_length_to(buf, MAJOR_NINT, (-1 - value) as u64);
393    }
394}
395
396/// Writes a CBOR array header directly into a buffer.
397pub fn encode_array_header_to(buf: &mut Vec<u8>, len: usize) {
398    encode_length_to(buf, MAJOR_ARRAY, len as u64);
399}
400
401/// Writes a CBOR map header directly into a buffer.
402pub fn encode_map_header_to(buf: &mut Vec<u8>, len: usize) {
403    encode_length_to(buf, MAJOR_MAP, len as u64);
404}
405
406/// The low level implementation of the CBOR decoder with only the
407/// handful of desired types supported.
408#[derive(Clone)]
409pub struct Decoder<'a> {
410    data: &'a [u8],
411    pos: usize,
412}
413
414impl<'a> Decoder<'a> {
415    /// Creates a decoder around a data blob.
416    pub fn new(data: &'a [u8]) -> Self {
417        Self { data, pos: 0 }
418    }
419
420    /// Terminates decoding and returns an error if trailing bytes remain.
421    pub fn finish(self) -> Result<(), Error> {
422        if self.pos != self.data.len() {
423            return Err(Error::TrailingBytes);
424        }
425        Ok(())
426    }
427
428    /// Decodes a positive integer, enforcing minimal canonicalness.
429    pub fn decode_uint(&mut self) -> Result<u64, Error> {
430        let (major, value) = self.decode_header()?;
431        if major != MAJOR_UINT {
432            return Err(Error::InvalidMajorType(major, MAJOR_UINT));
433        }
434        Ok(value)
435    }
436
437    /// Decodes a signed integer (major type 0 or 1).
438    pub fn decode_int(&mut self) -> Result<i64, Error> {
439        let (major, value) = self.decode_header()?;
440        match major {
441            MAJOR_UINT => {
442                if value > i64::MAX as u64 {
443                    return Err(Error::IntegerOverflow(false, value, i64::MAX as u64));
444                }
445                Ok(value as i64)
446            }
447            MAJOR_NINT => {
448                if value > i64::MAX as u64 {
449                    return Err(Error::IntegerOverflow(true, value, i64::MAX as u64));
450                }
451                Ok(-1 - value as i64)
452            }
453            _ => Err(Error::InvalidMajorType(major, MAJOR_UINT)),
454        }
455    }
456
457    /// Decodes a byte string.
458    pub fn decode_bytes(&mut self) -> Result<Vec<u8>, Error> {
459        // Extract the field type and attached length
460        let (major, len) = self.decode_header()?;
461        if major != MAJOR_BYTES {
462            return Err(Error::InvalidMajorType(major, MAJOR_BYTES));
463        }
464        // Retrieve the blob and return as is
465        let bytes = self.read_bytes(len)?;
466        Ok(bytes.to_vec())
467    }
468
469    /// Decodes a byte string into a fixed-size array.
470    pub fn decode_bytes_fixed<const N: usize>(&mut self) -> Result<[u8; N], Error> {
471        // Extract the field type and attached length
472        let (major, len) = self.decode_header()?;
473        if major != MAJOR_BYTES {
474            return Err(Error::InvalidMajorType(major, MAJOR_BYTES));
475        }
476        // Check that the length matches the expected array size
477        if len != N as u64 {
478            return Err(Error::UnexpectedItemCount(len, N));
479        }
480        // Retrieve the bytes and copy into the fixed-size array
481        let bytes = self.read_bytes(N as u64)?;
482        let mut array = [0u8; N];
483        array.copy_from_slice(bytes);
484        Ok(array)
485    }
486
487    /// Decodes a UTF-8 text string.
488    pub fn decode_text(&mut self) -> Result<String, Error> {
489        // Extract the field type and attached length
490        let (major, len) = self.decode_header()?;
491        if major != MAJOR_TEXT {
492            return Err(Error::InvalidMajorType(major, MAJOR_TEXT));
493        }
494        // Retrieve the blob and reinterpret as UTF-8
495        let bytes = self.read_bytes(len)?;
496        String::from_utf8(bytes.to_vec()).map_err(|_| Error::InvalidUtf8)
497    }
498
499    /// Decodes an array header, returning its length.
500    pub fn decode_array_header(&mut self) -> Result<u64, Error> {
501        // Extract the field type and attached length
502        let (major, len) = self.decode_header()?;
503        if major != MAJOR_ARRAY {
504            return Err(Error::InvalidMajorType(major, MAJOR_ARRAY));
505        }
506        // Sanity check: each element needs at least 1 byte
507        let remaining = (self.data.len() - self.pos) as u64;
508        if len > remaining {
509            return Err(Error::UnexpectedEof);
510        }
511        Ok(len)
512    }
513
514    /// Decodes a map header, returning the number of key-value pairs.
515    pub fn decode_map_header(&mut self) -> Result<u64, Error> {
516        // Extract the field type and attached length
517        let (major, len) = self.decode_header()?;
518        if major != MAJOR_MAP {
519            return Err(Error::InvalidMajorType(major, MAJOR_MAP));
520        }
521        // Sanity check: each key-value pair needs at least 2 bytes
522        let remaining = (self.data.len() - self.pos) as u64;
523        if len > remaining / 2 {
524            return Err(Error::UnexpectedEof);
525        }
526        Ok(len)
527    }
528
529    /// Decodes a CBOR boolean value.
530    pub fn decode_bool(&mut self) -> Result<bool, Error> {
531        if self.pos >= self.data.len() {
532            return Err(Error::UnexpectedEof);
533        }
534        let byte = self.data[self.pos];
535        match byte {
536            b if b == (MAJOR_SIMPLE << 5 | SIMPLE_FALSE) => {
537                self.pos += 1;
538                Ok(false)
539            }
540            b if b == (MAJOR_SIMPLE << 5 | SIMPLE_TRUE) => {
541                self.pos += 1;
542                Ok(true)
543            }
544            _ => Err(Error::InvalidMajorType(byte >> 5, MAJOR_SIMPLE)),
545        }
546    }
547
548    /// Decodes a CBOR null value.
549    pub fn decode_null(&mut self) -> Result<(), Error> {
550        if self.pos >= self.data.len() {
551            return Err(Error::UnexpectedEof);
552        }
553        let byte = self.data[self.pos];
554        if byte != (MAJOR_SIMPLE << 5 | SIMPLE_NULL) {
555            return Err(Error::InvalidMajorType(byte >> 5, MAJOR_SIMPLE));
556        }
557        self.pos += 1;
558        Ok(())
559    }
560
561    /// Checks if the next value is null without consuming it.
562    pub fn peek_null(&self) -> bool {
563        self.pos < self.data.len() && self.data[self.pos] == (MAJOR_SIMPLE << 5 | SIMPLE_NULL)
564    }
565
566    /// Returns the next signed integer value without consuming it.
567    pub fn peek_int(&self) -> Result<i64, Error> {
568        self.clone().decode_int()
569    }
570
571    /// Returns the next unsigned integer value without consuming it.
572    /// Unlike [`peek_int`](Self::peek_int), this only matches CBOR major type 0
573    /// (positive integers).
574    pub fn peek_uint(&self) -> Result<u64, Error> {
575        self.clone().decode_uint()
576    }
577
578    /// Extracts the major type for the next field and the integer
579    /// value embedded as the additional info.
580    fn decode_header(&mut self) -> Result<(u8, u64), Error> {
581        // Ensure there's still data left in the buffer
582        if self.pos >= self.data.len() {
583            return Err(Error::UnexpectedEof);
584        }
585        // Extract the type byte and split it apart
586        let byte = self.data[self.pos];
587        self.pos += 1;
588
589        let major = byte >> 5;
590        let info = byte & 0x1f;
591
592        // Extract the integer embedded in the info
593        let value = match info {
594            0..=23 => Ok(info as u64),
595            INFO_UINT8 => {
596                let bytes = self.read_bytes(1)?;
597                Ok(bytes[0] as u64)
598            }
599            INFO_UINT16 => {
600                let bytes = self.read_bytes(2)?;
601                Ok(u16::from_be_bytes([bytes[0], bytes[1]]) as u64)
602            }
603            INFO_UINT32 => {
604                let bytes = self.read_bytes(4)?;
605                Ok(u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as u64)
606            }
607            INFO_UINT64 => {
608                let bytes = self.read_bytes(8)?;
609                Ok(u64::from_be_bytes([
610                    bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
611                ]))
612            }
613            _ => Err(Error::InvalidAdditionalInfo(info)),
614        }?;
615
616        // Ensure it was canonical in the first place
617        if !match info {
618            0..=23 => value < 24,
619            INFO_UINT8 => value >= 24 && value <= u8::MAX as u64,
620            INFO_UINT16 => value > u8::MAX as u64 && value <= u16::MAX as u64,
621            INFO_UINT32 => value > u16::MAX as u64 && value <= u32::MAX as u64,
622            INFO_UINT64 => value > u32::MAX as u64,
623            _ => false,
624        } {
625            return Err(Error::NonCanonical);
626        }
627        Ok((major, value))
628    }
629
630    /// Retrieves the next handful of bytes from the buffer.
631    fn read_bytes(&mut self, len: u64) -> Result<&'a [u8], Error> {
632        // Ensure there's still enough data left in the buffer
633        if len > usize::MAX as u64 {
634            return Err(Error::UnexpectedEof);
635        }
636        let len = len as usize;
637
638        match self.pos.checked_add(len) {
639            None => return Err(Error::UnexpectedEof),
640            Some(end) => {
641                if end > self.data.len() {
642                    return Err(Error::UnexpectedEof);
643                }
644            }
645        }
646        // Retrieve the byte and move the cursor forward
647        let bytes = &self.data[self.pos..self.pos + len];
648        self.pos += len;
649
650        Ok(bytes)
651    }
652}
653
654/// The interface needed to encode a type to CBOR.
655pub trait Encode {
656    /// Writes the CBOR encoding directly into an existing buffer.
657    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error>;
658}
659
660/// The interface needed to decode a type from CBOR.
661pub trait Decode: Sized {
662    /// Converts CBOR to the type.
663    fn decode_cbor(data: &[u8]) -> Result<Self, Error>;
664
665    /// Converts CBOR to the type, ignoring any trailing data.
666    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error>;
667}
668
669// Encoder and decoder implementation for booleans.
670impl Encode for bool {
671    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
672        buf.push(MAJOR_SIMPLE << 5 | if *self { SIMPLE_TRUE } else { SIMPLE_FALSE });
673        Ok(())
674    }
675}
676
677impl Decode for bool {
678    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
679        let mut decoder = Decoder::new(data);
680        let value = decoder.decode_bool()?;
681        decoder.finish()?;
682        Ok(value)
683    }
684
685    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
686        decoder.decode_bool()
687    }
688}
689
690// Encoder and decoder implementation for positive integers.
691impl Encode for u64 {
692    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
693        encode_length_to(buf, MAJOR_UINT, *self);
694        Ok(())
695    }
696}
697
698impl Decode for u64 {
699    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
700        let mut decoder = Decoder::new(data);
701        let value = decoder.decode_uint()?;
702        decoder.finish()?;
703        Ok(value)
704    }
705
706    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
707        decoder.decode_uint()
708    }
709}
710
711// Encoder and decoder implementation for signed integers.
712impl Encode for i64 {
713    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
714        encode_int_to(buf, *self);
715        Ok(())
716    }
717}
718
719impl Decode for i64 {
720    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
721        let mut decoder = Decoder::new(data);
722        let value = decoder.decode_int()?;
723        decoder.finish()?;
724        Ok(value)
725    }
726
727    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
728        decoder.decode_int()
729    }
730}
731
732// Encoder and decoder implementation for dynamic byte blobs.
733impl Encode for Vec<u8> {
734    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
735        encode_length_to(buf, MAJOR_BYTES, self.len() as u64);
736        buf.extend_from_slice(self);
737        Ok(())
738    }
739}
740
741impl Encode for &[u8] {
742    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
743        encode_length_to(buf, MAJOR_BYTES, self.len() as u64);
744        buf.extend_from_slice(self);
745        Ok(())
746    }
747}
748
749impl Decode for Vec<u8> {
750    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
751        let mut decoder = Decoder::new(data);
752        let value = decoder.decode_bytes()?;
753        decoder.finish()?;
754        Ok(value)
755    }
756
757    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
758        decoder.decode_bytes()
759    }
760}
761
762// Encoder and decoder implementation for fixed byte blobs.
763impl<const N: usize> Encode for [u8; N] {
764    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
765        encode_length_to(buf, MAJOR_BYTES, N as u64);
766        buf.extend_from_slice(self);
767        Ok(())
768    }
769}
770
771impl<const N: usize> Decode for [u8; N] {
772    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
773        let mut decoder = Decoder::new(data);
774        let value = decoder.decode_bytes_fixed::<N>()?;
775        decoder.finish()?;
776        Ok(value)
777    }
778
779    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
780        decoder.decode_bytes_fixed::<N>()
781    }
782}
783
784// Encoder and decoder implementation for UTF-8 strings.
785impl Encode for String {
786    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
787        encode_length_to(buf, MAJOR_TEXT, self.len() as u64);
788        buf.extend_from_slice(self.as_bytes());
789        Ok(())
790    }
791}
792
793impl Encode for &str {
794    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
795        encode_length_to(buf, MAJOR_TEXT, self.len() as u64);
796        buf.extend_from_slice(self.as_bytes());
797        Ok(())
798    }
799}
800
801impl Decode for String {
802    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
803        let mut decoder = Decoder::new(data);
804        let value = decoder.decode_text()?;
805        decoder.finish()?;
806        Ok(value)
807    }
808
809    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
810        decoder.decode_text()
811    }
812}
813
814// Encoder and decoder implementation for the empty tuple.
815impl Encode for () {
816    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
817        encode_length_to(buf, MAJOR_ARRAY, 0);
818        Ok(())
819    }
820}
821
822impl Decode for () {
823    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
824        let mut decoder = Decoder::new(data);
825        let len = decoder.decode_array_header()?;
826        if len != 0 {
827            return Err(Error::UnexpectedItemCount(len, 0));
828        }
829        decoder.finish()?;
830        Ok(())
831    }
832
833    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
834        let len = decoder.decode_array_header()?;
835        if len != 0 {
836            return Err(Error::UnexpectedItemCount(len, 0));
837        }
838        Ok(())
839    }
840}
841
842// Encoder and decoder implementation for real tuples.
843macro_rules! impl_tuple {
844    ($($t:ident),+) => {
845        impl<$($t: Encode),+> Encode for ($($t,)+) {
846            fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
847                // Encode the length of the tuple
848                let len = args!($($t),+);
849                encode_length_to(buf, MAJOR_ARRAY, len as u64);
850
851                // Encode all the tuple elements individually
852                let ($($t,)+) = self;
853                $($t.encode_cbor_to(buf)?;)+
854                Ok(())
855            }
856        }
857
858        impl<$($t: Decode),+> Decode for ($($t,)+) {
859            fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
860                let mut decoder = Decoder::new(data);
861
862                // Decode the length of the tuple
863                let len = decoder.decode_array_header()?;
864                let exp = args!($($t),+);
865                if len != exp as u64 {
866                    return Err(Error::UnexpectedItemCount(len, exp));
867                }
868                // Decode all the tuple elements individually
869                $(
870                    let $t = $t::decode_cbor_notrail(&mut decoder)?;
871                )+
872                decoder.finish()?;
873                Ok(($($t,)+))
874            }
875
876            fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
877                // Decode the length of the tuple
878                let len = decoder.decode_array_header()?;
879                let exp = args!($($t),+);
880                if len != exp as u64 {
881                    return Err(Error::UnexpectedItemCount(len, exp));
882                }
883                // Decode all the tuple elements individually
884                $(
885                    let $t = $t::decode_cbor_notrail(decoder)?;
886                )+
887                Ok(($($t,)+))
888            }
889        }
890    };
891}
892
893macro_rules! args {
894    ($($t:ident),+) => { args!(@count $($t),+) };
895    (@count $t1:ident) => { 1 };
896    (@count $t1:ident, $($t:ident),+) => { 1 + args!(@count $($t),+) };
897}
898
899#[allow(non_snake_case)]
900mod tuple_impls {
901    use super::*;
902
903    impl_tuple!(T1);
904    impl_tuple!(T1, T2);
905    impl_tuple!(T1, T2, T3);
906    impl_tuple!(T1, T2, T3, T4);
907    impl_tuple!(T1, T2, T3, T4, T5);
908    impl_tuple!(T1, T2, T3, T4, T5, T6);
909    impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
910    impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
911}
912
913// Blanket encoder for references.
914impl<T: Encode> Encode for &T {
915    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
916        (*self).encode_cbor_to(buf)
917    }
918}
919
920/// Constant for convenient CBOR null encoding, the [`Null`] unit value.
921pub const NULL: Null = Null;
922
923/// A unit type that encodes/decodes as CBOR null (0xf6).
924#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
925pub struct Null;
926
927impl Encode for Null {
928    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
929        buf.push(MAJOR_SIMPLE << 5 | SIMPLE_NULL);
930        Ok(())
931    }
932}
933
934impl Decode for Null {
935    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
936        let mut decoder = Decoder::new(data);
937        let result = Self::decode_cbor_notrail(&mut decoder)?;
938        decoder.finish()?;
939        Ok(result)
940    }
941
942    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
943        decoder.decode_null()?;
944        Ok(Null)
945    }
946}
947
948// Encoder and decoder implementation for Option<T> (None encodes as null).
949impl<T: Encode> Encode for Option<T> {
950    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
951        match self {
952            Some(value) => value.encode_cbor_to(buf),
953            None => {
954                buf.push(MAJOR_SIMPLE << 5 | SIMPLE_NULL);
955                Ok(())
956            }
957        }
958    }
959}
960
961impl<T: Decode> Decode for Option<T> {
962    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
963        let mut decoder = Decoder::new(data);
964        let result = Self::decode_cbor_notrail(&mut decoder)?;
965        decoder.finish()?;
966        Ok(result)
967    }
968
969    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
970        if decoder.peek_null() {
971            decoder.decode_null()?;
972            Ok(None)
973        } else {
974            Ok(Some(T::decode_cbor_notrail(decoder)?))
975        }
976    }
977}
978
979/// A `Vec<T>` wrapper that encodes and decodes as a CBOR array.
980#[derive(Clone, Debug, Default, PartialEq, Eq)]
981pub struct Array<T>(pub Vec<T>);
982
983impl<T> std::ops::Deref for Array<T> {
984    type Target = Vec<T>;
985
986    fn deref(&self) -> &Self::Target {
987        &self.0
988    }
989}
990
991impl<T> std::ops::DerefMut for Array<T> {
992    fn deref_mut(&mut self) -> &mut Self::Target {
993        &mut self.0
994    }
995}
996
997impl<T> From<Vec<T>> for Array<T> {
998    fn from(v: Vec<T>) -> Self {
999        Array(v)
1000    }
1001}
1002
1003impl<T: Encode> Encode for Array<T> {
1004    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
1005        encode_length_to(buf, MAJOR_ARRAY, self.0.len() as u64);
1006        for item in &self.0 {
1007            item.encode_cbor_to(buf)?;
1008        }
1009        Ok(())
1010    }
1011}
1012
1013impl<T: Decode> Decode for Array<T> {
1014    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
1015        let mut decoder = Decoder::new(data);
1016        let result = Self::decode_cbor_notrail(&mut decoder)?;
1017        decoder.finish()?;
1018        Ok(result)
1019    }
1020
1021    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
1022        let len = decoder.decode_array_header()?;
1023
1024        // Cap pre-allocation: the wire can't produce more in-memory elements
1025        // than remaining bytes / per-element size. Prevents OOM from inflated
1026        // headers. .max(1) guards against zero-sized types.
1027        let wire_remaining = decoder.data.len() - decoder.pos;
1028        let elem_size = std::mem::size_of::<T>().max(1);
1029        let safe_cap = wire_remaining / elem_size;
1030        let mut items = Vec::with_capacity((len as usize).min(safe_cap));
1031
1032        for _ in 0..len {
1033            items.push(T::decode_cbor_notrail(decoder)?);
1034        }
1035        Ok(Array(items))
1036    }
1037}
1038
1039/// A `[T; N]` wrapper that encodes and decodes as a CBOR array with an exact
1040/// element count. Decoding rejects any length other than N.
1041#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1042pub struct FixedArray<T, const N: usize>(pub [T; N]);
1043
1044impl<T, const N: usize> std::ops::Deref for FixedArray<T, N> {
1045    type Target = [T; N];
1046
1047    fn deref(&self) -> &Self::Target {
1048        &self.0
1049    }
1050}
1051
1052impl<T, const N: usize> std::ops::DerefMut for FixedArray<T, N> {
1053    fn deref_mut(&mut self) -> &mut Self::Target {
1054        &mut self.0
1055    }
1056}
1057
1058impl<T, const N: usize> From<[T; N]> for FixedArray<T, N> {
1059    fn from(arr: [T; N]) -> Self {
1060        FixedArray(arr)
1061    }
1062}
1063
1064impl<T: Encode, const N: usize> Encode for FixedArray<T, N> {
1065    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
1066        encode_length_to(buf, MAJOR_ARRAY, N as u64);
1067        for item in &self.0 {
1068            item.encode_cbor_to(buf)?;
1069        }
1070        Ok(())
1071    }
1072}
1073
1074impl<T: Decode, const N: usize> Decode for FixedArray<T, N> {
1075    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
1076        let mut decoder = Decoder::new(data);
1077        let result = Self::decode_cbor_notrail(&mut decoder)?;
1078        decoder.finish()?;
1079        Ok(result)
1080    }
1081
1082    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
1083        let len = decoder.decode_array_header()?;
1084        if len != N as u64 {
1085            return Err(Error::UnexpectedItemCount(len, N));
1086        }
1087        let mut items: Vec<T> = Vec::with_capacity(N);
1088        for _ in 0..N {
1089            items.push(T::decode_cbor_notrail(decoder)?);
1090        }
1091        let items: [T; N] = items
1092            .try_into()
1093            .map_err(|_| Error::UnexpectedItemCount(len, N))?;
1094        Ok(FixedArray(items))
1095    }
1096}
1097
1098/// Direct map-entry encoding for derive-generated map-mode
1099/// structs. This avoids map encode/decode roundtrips when flattening embeds.
1100pub trait MapEncode {
1101    /// Appends this value's map entries to the shared buffer, key by key.
1102    fn encode_map(&self, enc: &mut MapEncodeBuffer) -> Result<(), Error>;
1103}
1104
1105/// A collector of CBOR map entries in a single shared buffer,
1106/// recording (key, start, end) offsets. This avoids per-field allocation:
1107/// all encoded values are written contiguously into `data`.
1108pub struct MapEncodeBuffer {
1109    /// Encoded values, written back to back.
1110    pub data: Vec<u8>,
1111    /// Key and the value's byte range within `data`, one per entry.
1112    pub entries: Vec<(i64, usize, usize)>,
1113}
1114
1115impl MapEncodeBuffer {
1116    /// Creates a new buffer pre-sized for the expected number of entries.
1117    pub fn new(capacity: usize) -> Self {
1118        Self {
1119            data: Vec::with_capacity(capacity * 9), // ~9 bytes per field
1120            entries: Vec::with_capacity(capacity),
1121        }
1122    }
1123
1124    /// Encodes a required field directly into the shared buffer.
1125    pub fn push<T: Encode>(&mut self, key: i64, value: &T) -> Result<(), Error> {
1126        let start = self.data.len();
1127        value.encode_cbor_to(&mut self.data)?;
1128        let end = self.data.len();
1129        self.entries.push((key, start, end));
1130        Ok(())
1131    }
1132
1133    /// Encodes an optional field; omits the entry entirely when None.
1134    pub fn push_optional<T: Encode>(&mut self, key: i64, value: &Option<T>) -> Result<(), Error> {
1135        if let Some(v) = value {
1136            self.push(key, v)?;
1137        }
1138        Ok(())
1139    }
1140
1141    /// Assembles the final CBOR map into the provided buffer. Sorts entries
1142    /// by CBOR key order if not already sorted, then verifies no duplicate keys.
1143    pub fn finish_to(mut self, out: &mut Vec<u8>) -> Result<(), Error> {
1144        // Check if already in order (common case: keys from embeds interleave nicely)
1145        let ordered = self
1146            .entries
1147            .windows(2)
1148            .all(|w| cbor_key_cmp(w[0].0, w[1].0) == Ordering::Less);
1149
1150        if !ordered {
1151            self.entries.sort_unstable_by(|a, b| cbor_key_cmp(a.0, b.0));
1152        }
1153        // Verify no duplicates after sorting
1154        for w in self.entries.windows(2) {
1155            if w[0].0 == w[1].0 {
1156                return Err(Error::DuplicateMapKey(w[0].0));
1157            }
1158        }
1159        // Assemble output: map header + sorted key-value pairs
1160        out.reserve(self.data.len() + self.entries.len() * 10 + 5);
1161        encode_length_to(out, MAJOR_MAP, self.entries.len() as u64);
1162        for &(key, start, end) in &self.entries {
1163            encode_int_to(out, key);
1164            out.extend_from_slice(&self.data[start..end]);
1165        }
1166        Ok(())
1167    }
1168}
1169
1170/// Direct map-entry decoding for derive-generated map-mode
1171/// structs. Implementations consume claimed keys from `entries`.
1172pub trait MapDecode: Sized {
1173    /// Returns the map keys this type consumes, sorted by [`cbor_key_cmp`].
1174    fn cbor_map_keys() -> &'static [i64];
1175    /// Builds the value from the entries it claims, leaving the rest in place.
1176    fn decode_map<'a, E: MapEntryAccess<'a>>(entries: &mut E) -> Result<Self, Error>;
1177}
1178
1179/// Key-based access to encoded CBOR map values.
1180pub trait MapEntryAccess<'a> {
1181    /// Removes and returns the raw value stored under the key, if still present.
1182    fn take(&mut self, key: i64) -> Option<&'a [u8]>;
1183    /// Reports whether an unclaimed value is stored under the key.
1184    fn contains(&self, key: i64) -> bool;
1185    /// Reports whether every entry has been claimed.
1186    fn is_empty(&self) -> bool;
1187    /// Lists the keys whose values have not been claimed yet.
1188    fn remaining_keys(&self) -> Vec<i64>;
1189}
1190
1191/// A deterministic CBOR map stored as key/value slots, supporting
1192/// efficient key-based extraction without rebuilding tree maps.
1193#[derive(Clone, Debug, PartialEq, Eq)]
1194pub struct MapEntries<'a> {
1195    entries: Vec<(i64, Option<&'a [u8]>)>,
1196    remaining: usize,
1197}
1198
1199impl<'a> MapEntries<'a> {
1200    /// Creates from entries that are already in CBOR deterministic key order
1201    /// (as validated by [`decode_map_entries_slices_notrail`]). Skips re-sorting.
1202    pub fn new(entries: Vec<(i64, &'a [u8])>) -> Self {
1203        let len = entries.len();
1204        let entries: Vec<(i64, Option<&'a [u8]>)> =
1205            entries.into_iter().map(|(k, v)| (k, Some(v))).collect();
1206        Self {
1207            remaining: len,
1208            entries,
1209        }
1210    }
1211
1212    /// Removes and returns the raw value stored under the key, if still present.
1213    pub fn take(&mut self, key: i64) -> Option<&'a [u8]> {
1214        let index = self
1215            .entries
1216            .binary_search_by(|(k, _)| cbor_key_cmp(*k, key))
1217            .ok()?;
1218        let value = self.entries[index].1.take();
1219        if value.is_some() {
1220            self.remaining -= 1;
1221        }
1222        value
1223    }
1224
1225    /// Reports whether every entry has been claimed.
1226    pub fn is_empty(&self) -> bool {
1227        self.remaining == 0
1228    }
1229
1230    /// Reports whether an unclaimed value is stored under the key.
1231    pub fn contains(&self, key: i64) -> bool {
1232        self.entries
1233            .binary_search_by(|(k, _)| cbor_key_cmp(*k, key))
1234            .ok()
1235            .and_then(|index| self.entries[index].1.as_ref())
1236            .is_some()
1237    }
1238
1239    /// Lists the keys whose values have not been claimed yet.
1240    pub fn remaining_keys(&self) -> Vec<i64> {
1241        self.entries
1242            .iter()
1243            .filter_map(|(k, v)| v.as_ref().map(|_| *k))
1244            .collect()
1245    }
1246}
1247
1248impl<'a> MapEntryAccess<'a> for MapEntries<'a> {
1249    fn take(&mut self, key: i64) -> Option<&'a [u8]> {
1250        MapEntries::take(self, key)
1251    }
1252
1253    fn contains(&self, key: i64) -> bool {
1254        MapEntries::contains(self, key)
1255    }
1256
1257    fn is_empty(&self) -> bool {
1258        MapEntries::is_empty(self)
1259    }
1260
1261    fn remaining_keys(&self) -> Vec<i64> {
1262        MapEntries::remaining_keys(self)
1263    }
1264}
1265
1266/// A view into `MapEntries` restricted to a fixed key set.
1267pub struct MapEntriesScoped<'a, 'b, E: MapEntryAccess<'a>> {
1268    entries: &'b mut E,
1269    keys: &'b [i64],
1270    marker: std::marker::PhantomData<&'a ()>,
1271}
1272
1273impl<'a, 'b, E: MapEntryAccess<'a>> MapEntriesScoped<'a, 'b, E> {
1274    /// Restricts `entries` to the given keys, which must be sorted by [`cbor_key_cmp`].
1275    pub fn new(entries: &'b mut E, keys: &'b [i64]) -> Self {
1276        Self {
1277            entries,
1278            keys,
1279            marker: std::marker::PhantomData,
1280        }
1281    }
1282
1283    /// Checks whether a key belongs to this scoped view. The keys slice
1284    /// originates from `cbor_map_keys()` which is sorted by `cbor_key_cmp`,
1285    /// so a binary search replaces the former linear scan.
1286    fn key_allowed(&self, key: i64) -> bool {
1287        self.keys
1288            .binary_search_by(|k| cbor_key_cmp(*k, key))
1289            .is_ok()
1290    }
1291}
1292
1293impl<'a, 'b, E: MapEntryAccess<'a>> MapEntryAccess<'a> for MapEntriesScoped<'a, 'b, E> {
1294    fn take(&mut self, key: i64) -> Option<&'a [u8]> {
1295        if self.key_allowed(key) {
1296            self.entries.take(key)
1297        } else {
1298            None
1299        }
1300    }
1301
1302    fn contains(&self, key: i64) -> bool {
1303        self.key_allowed(key) && self.entries.contains(key)
1304    }
1305
1306    fn is_empty(&self) -> bool {
1307        // We are iterating self.keys, so every key is allowed by
1308        // definition; skip key_allowed and probe the parent directly.
1309        self.keys.iter().all(|k| !self.entries.contains(*k))
1310    }
1311
1312    fn remaining_keys(&self) -> Vec<i64> {
1313        // Same: iterating self.keys, so key_allowed is always true.
1314        self.keys
1315            .iter()
1316            .copied()
1317            .filter(|k| self.entries.contains(*k))
1318            .collect()
1319    }
1320}
1321
1322/// A placeholder type to allow only partially parsing CBOR objects when
1323/// some part might depend on another (e.g. version tag, method in an RPC, etc).
1324///
1325/// Encoding copies the bytes verbatim, without checking that they contain even
1326/// one valid CBOR item. Decoding traverses one item's structure and checks its
1327/// headers, lengths, supported types, and nesting depth, but does not validate
1328/// text as UTF-8 or check map key types, order, or duplicates. Use [`verify`] on
1329/// the bytes when full validation of this crate's CBOR subset is required.
1330#[derive(Clone, Debug, PartialEq, Eq)]
1331pub struct Raw(pub Vec<u8>);
1332
1333impl std::ops::Deref for Raw {
1334    type Target = Vec<u8>;
1335
1336    fn deref(&self) -> &Self::Target {
1337        &self.0
1338    }
1339}
1340
1341impl std::ops::DerefMut for Raw {
1342    fn deref_mut(&mut self) -> &mut Self::Target {
1343        &mut self.0
1344    }
1345}
1346
1347impl Encode for Raw {
1348    fn encode_cbor_to(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
1349        buf.extend_from_slice(&self.0);
1350        Ok(())
1351    }
1352}
1353
1354impl Decode for Raw {
1355    fn decode_cbor(data: &[u8]) -> Result<Self, Error> {
1356        let mut decoder = Decoder::new(data);
1357        let result = Self::decode_cbor_notrail(&mut decoder)?;
1358        decoder.finish()?;
1359        Ok(result)
1360    }
1361
1362    fn decode_cbor_notrail(decoder: &mut Decoder<'_>) -> Result<Self, Error> {
1363        let start = decoder.pos;
1364        skip_object(decoder, MAX_DEPTH)?;
1365        let end = decoder.pos;
1366        Ok(Raw(decoder.data[start..end].to_vec()))
1367    }
1368}
1369
1370/// Advances the decoder past one CBOR item without validation. It
1371/// does do some minimal type checks as walking the CBOR does require walking
1372/// all the inner fields too. The depth parameter limits nesting to prevent
1373/// stack overflow from malicious inputs.
1374fn skip_object(decoder: &mut Decoder<'_>, depth: usize) -> Result<(), Error> {
1375    if depth == 0 {
1376        return Err(Error::MaxDepthExceeded(MAX_DEPTH));
1377    }
1378    let (major, value) = decoder.decode_header()?;
1379    match major {
1380        MAJOR_UINT | MAJOR_NINT => Ok(()),
1381        MAJOR_BYTES | MAJOR_TEXT => {
1382            decoder.read_bytes(value)?;
1383            Ok(())
1384        }
1385        MAJOR_ARRAY => {
1386            for _ in 0..value {
1387                skip_object(decoder, depth - 1)?;
1388            }
1389            Ok(())
1390        }
1391        MAJOR_MAP => {
1392            for _ in 0..value {
1393                skip_object(decoder, depth - 1)?;
1394                skip_object(decoder, depth - 1)?;
1395            }
1396            Ok(())
1397        }
1398        MAJOR_SIMPLE
1399            if value == SIMPLE_FALSE as u64
1400                || value == SIMPLE_TRUE as u64
1401                || value == SIMPLE_NULL as u64 =>
1402        {
1403            Ok(())
1404        }
1405        _ => Err(Error::UnsupportedType(major)),
1406    }
1407}
1408
1409/// Compares two i64 keys according to CBOR deterministic encoding
1410/// order (RFC 8949 Section 4.2.1): bytewise lexicographic order of encoded keys.
1411///
1412/// For integers this means: positive integers (0, 1, 2, ...) come before negative
1413/// integers (-1, -2, -3, ...), and within each category they're ordered by their
1414/// encoded length first, then by value.
1415pub fn cbor_key_cmp(a: i64, b: i64) -> Ordering {
1416    // CBOR deterministic encoding of integer keys:
1417    //   - Major type 0 (non-negative) encodes as 0x00..0x1b; shorter forms sort first.
1418    //   - Major type 1 (negative)     encodes as 0x20..0x3b; shorter forms sort first.
1419    //   - Major 0 bytes always < Major 1 bytes, so all non-negatives sort before negatives.
1420    //
1421    // Within each sign category, CBOR uses canonical shortest-form encoding,
1422    // so smaller absolute values get shorter encodings which sort first; equal
1423    // lengths are ordered by value. This matches plain unsigned comparison of
1424    // the wire value (the value itself for non-negative, (-1 - n) for negative n).
1425    match (a >= 0, b >= 0) {
1426        (true, true) => (a as u64).cmp(&(b as u64)),
1427        (false, false) => {
1428            // Wire value for negative n is (-1 - n) as u64.
1429            // -1 → wire 0, -2 → wire 1, … so smaller absolute value sorts first.
1430            ((-1 - a) as u64).cmp(&((-1 - b) as u64))
1431        }
1432        (true, false) => Ordering::Less,
1433        (false, true) => Ordering::Greater,
1434    }
1435}
1436
1437/// Reads a CBOR map from the decoder and returns its
1438/// entries as (key, raw_value) pairs.
1439pub fn decode_map_entries_notrail(dec: &mut Decoder<'_>) -> Result<Vec<(i64, Raw)>, Error> {
1440    let entries = decode_map_entries_slices_notrail(dec)?;
1441    Ok(entries
1442        .into_iter()
1443        .map(|(k, v)| (k, Raw(v.to_vec())))
1444        .collect())
1445}
1446
1447/// Reads a CBOR map from the decoder and
1448/// returns borrowed slices for each value.
1449pub fn decode_map_entries_slices_notrail<'a>(
1450    dec: &mut Decoder<'a>,
1451) -> Result<Vec<(i64, &'a [u8])>, Error> {
1452    let len = dec.decode_map_header()?;
1453
1454    // Cap pre-allocation to prevent memory amplification from untrusted
1455    // map headers. Each entry is ~24 bytes in memory (i64 + fat pointer)
1456    // but only needs 2 bytes on the wire, giving a ~12x amplification
1457    // factor. Dividing the remaining wire bytes by the in-memory entry
1458    // size keeps the upfront allocation proportional to the input. The
1459    // +16 avoids needless reallocation for the small maps that dominate
1460    // real-world CBOR traffic.
1461    let wire_remaining = dec.data.len() - dec.pos;
1462    let entry_mem_size = 8 + 2 * std::mem::size_of::<usize>(); // sizeof (i64, &[u8])
1463    let safe_cap = (wire_remaining / entry_mem_size).saturating_add(16);
1464    let mut entries = Vec::with_capacity((len as usize).min(safe_cap));
1465    let mut prev_key: Option<i64> = None;
1466    for _ in 0..len {
1467        let key = dec.decode_int()?;
1468        if let Some(prev) = prev_key
1469            && cbor_key_cmp(prev, key) != Ordering::Less
1470        {
1471            return Err(if prev == key {
1472                Error::DuplicateMapKey(key)
1473            } else {
1474                Error::InvalidMapKeyOrder(key, prev)
1475            });
1476        }
1477        prev_key = Some(key);
1478        let start = dec.pos;
1479        skip_object(dec, MAX_DEPTH)?;
1480        let end = dec.pos;
1481        entries.push((key, &dec.data[start..end]));
1482    }
1483    Ok(entries)
1484}
1485
1486/// Reads a CBOR map from raw bytes and returns its entries
1487/// as (key, raw_value) pairs.
1488pub fn decode_map_entries(data: &[u8]) -> Result<Vec<(i64, Raw)>, Error> {
1489    let mut dec = Decoder::new(data);
1490    let entries = decode_map_entries_notrail(&mut dec)?;
1491    dec.finish()?;
1492    Ok(entries)
1493}
1494
1495/// Encodes a list of (key, raw_value) pairs as a CBOR map.
1496/// The entries must already be sorted by CBOR key order.
1497pub fn encode_map_entries(entries: &[(i64, Raw)]) -> Vec<u8> {
1498    let mut enc = Encoder::new();
1499    enc.encode_map_header(entries.len());
1500    for (key, value) in entries {
1501        enc.encode_int(*key);
1502        enc.extend(&value.0);
1503    }
1504    enc.finish()
1505}
1506
1507/// Verifies a single CBOR item without full deserialization. The depth
1508/// parameter limits nesting to prevent stack overflow from malicious inputs.
1509fn verify_object(decoder: &mut Decoder, depth: usize) -> Result<(), Error> {
1510    if depth == 0 {
1511        return Err(Error::MaxDepthExceeded(MAX_DEPTH));
1512    }
1513    let (major, value) = decoder.decode_header()?;
1514
1515    match major {
1516        MAJOR_UINT | MAJOR_NINT => {
1517            // Integers are valid (canonicalness was already verified in the
1518            // header decoding). Overflow checking is done at decode time based
1519            // on the target type (u64 vs i64).
1520            Ok(())
1521        }
1522        MAJOR_BYTES => {
1523            // Opaque bytes are always valid, skip over
1524            _ = decoder.read_bytes(value)?;
1525            Ok(())
1526        }
1527        MAJOR_TEXT => {
1528            // Verify that the text is indeed UTF-8
1529            let bytes = decoder.read_bytes(value)?;
1530            std::str::from_utf8(bytes).map_err(|_| Error::InvalidUtf8)?;
1531            Ok(())
1532        }
1533        MAJOR_ARRAY => {
1534            // Recursively verify each array element
1535            for _ in 0..value {
1536                verify_object(decoder, depth - 1)?;
1537            }
1538            Ok(())
1539        }
1540        MAJOR_MAP => {
1541            // Verify map has integer keys in deterministic order
1542            let mut prev_key: Option<i64> = None;
1543
1544            for _ in 0..value {
1545                // Decode and verify the key is an integer
1546                let key = decoder.decode_int()?;
1547
1548                // Verify deterministic ordering and no duplicate keys
1549                if let Some(prev) = prev_key
1550                    && cbor_key_cmp(prev, key) != Ordering::Less
1551                {
1552                    return Err(if prev == key {
1553                        Error::DuplicateMapKey(key)
1554                    } else {
1555                        Error::InvalidMapKeyOrder(key, prev)
1556                    });
1557                }
1558                prev_key = Some(key);
1559
1560                // Recursively verify the value
1561                verify_object(decoder, depth - 1)?;
1562            }
1563            Ok(())
1564        }
1565        MAJOR_SIMPLE
1566            if value == SIMPLE_FALSE as u64
1567                || value == SIMPLE_TRUE as u64
1568                || value == SIMPLE_NULL as u64 =>
1569        {
1570            // Booleans and null are valid simple values
1571            Ok(())
1572        }
1573        _ => {
1574            // Any other major type is disallowed
1575            Err(Error::UnsupportedType(major))
1576        }
1577    }
1578}
1579
1580#[cfg(test)]
1581mod tests {
1582    use super::*;
1583
1584    /// Tests that booleans encode correctly.
1585    #[test]
1586    fn test_bool_encoding() {
1587        assert_eq!(encode(false).unwrap(), vec![0xf4]);
1588        assert_eq!(encode(true).unwrap(), vec![0xf5]);
1589    }
1590
1591    /// Tests that booleans decode correctly.
1592    #[test]
1593    fn test_bool_decoding() {
1594        assert!(!decode::<bool>(&[0xf4]).unwrap());
1595        assert!(decode::<bool>(&[0xf5]).unwrap());
1596
1597        // Invalid values should fail
1598        assert!(decode::<bool>(&[0xf6]).is_err()); // null
1599        assert!(decode::<bool>(&[0x00]).is_err()); // integer
1600    }
1601
1602    /// Tests that null encodes correctly.
1603    #[test]
1604    fn test_null_encoding() {
1605        assert_eq!(encode(None::<u64>).unwrap(), vec![0xf6]);
1606        assert_eq!(encode(Some(42u64)).unwrap(), encode(42u64).unwrap());
1607    }
1608
1609    /// Tests that null decodes correctly.
1610    #[test]
1611    fn test_null_decoding() {
1612        assert_eq!(decode::<Option<u64>>(&[0xf6]).unwrap(), None);
1613        assert_eq!(
1614            decode::<Option<u64>>(&encode(42u64).unwrap()).unwrap(),
1615            Some(42)
1616        );
1617
1618        // Nested options
1619        assert_eq!(decode::<Option<bool>>(&[0xf4]).unwrap(), Some(false));
1620        assert_eq!(decode::<Option<bool>>(&[0xf5]).unwrap(), Some(true));
1621        assert_eq!(decode::<Option<bool>>(&[0xf6]).unwrap(), None);
1622
1623        // Null type
1624        assert_eq!(decode::<Null>(&[0xf6]).unwrap(), Null);
1625        assert!(decode::<Null>(&[0xf4]).is_err()); // false is not null
1626        assert!(decode::<Null>(&[0x00]).is_err()); // integer is not null
1627    }
1628
1629    /// Tests that positive integers encode correctly across the various ranges
1630    /// that CBOR special cases.
1631    #[test]
1632    fn test_uint_encoding() {
1633        let cases = [
1634            (0u64, vec![0x00]),
1635            (23u64, vec![0x17]),
1636            (24u64, vec![0x18, 0x18]),
1637            (u8::MAX as u64, vec![0x18, 0xff]),
1638            (u8::MAX as u64 + 1, vec![0x19, 0x01, 0x00]),
1639            (u16::MAX as u64, vec![0x19, 0xff, 0xff]),
1640            (u16::MAX as u64 + 1, vec![0x1a, 0x00, 0x01, 0x00, 0x00]),
1641            (u32::MAX as u64, vec![0x1a, 0xff, 0xff, 0xff, 0xff]),
1642            (
1643                u32::MAX as u64 + 1,
1644                vec![0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00],
1645            ),
1646            (
1647                u64::MAX,
1648                vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1649            ),
1650        ];
1651
1652        for (value, expected) in cases {
1653            assert_eq!(
1654                encode(value).unwrap(),
1655                expected,
1656                "encoding failed for value {}",
1657                value
1658            );
1659        }
1660    }
1661
1662    /// Tests that positive integers decode correctly across the various ranges
1663    /// that CBOR special cases.
1664    #[test]
1665    fn test_uint_decoding() {
1666        let cases = [
1667            (vec![0x00], 0u64),
1668            (vec![0x17], 23u64),
1669            (vec![0x18, 0x18], 24u64),
1670            (vec![0x18, 0xff], u8::MAX as u64),
1671            (vec![0x19, 0x01, 0x00], u8::MAX as u64 + 1),
1672            (vec![0x19, 0xff, 0xff], u16::MAX as u64),
1673            (vec![0x1a, 0x00, 0x01, 0x00, 0x00], u16::MAX as u64 + 1),
1674            (vec![0x1a, 0xff, 0xff, 0xff, 0xff], u32::MAX as u64),
1675            (
1676                vec![0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00],
1677                u32::MAX as u64 + 1,
1678            ),
1679            (
1680                vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1681                u64::MAX,
1682            ),
1683        ];
1684
1685        for (data, expected) in cases {
1686            assert_eq!(
1687                decode::<u64>(&data).unwrap(),
1688                expected,
1689                "decoding failed for data {:?}",
1690                data
1691            );
1692        }
1693    }
1694
1695    /// Tests that positive integers are rejected for invalid size / encoding
1696    /// combinations.
1697    #[test]
1698    fn test_uint_rejection() {
1699        // Values 0-23 must use direct embedding
1700        for value in 0..24u64 {
1701            // Should fail with INFO_UINT8
1702            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT8, value as u8];
1703            assert!(decode::<u64>(&data).is_err());
1704
1705            // Should fail with INFO_UINT16
1706            data = vec![MAJOR_UINT << 5 | INFO_UINT16];
1707            data.extend_from_slice(&(value as u16).to_be_bytes());
1708            assert!(decode::<u64>(&data).is_err());
1709
1710            // Should fail with INFO_UINT32
1711            data = vec![MAJOR_UINT << 5 | INFO_UINT32];
1712            data.extend_from_slice(&(value as u32).to_be_bytes());
1713            assert!(decode::<u64>(&data).is_err());
1714
1715            // Should fail with INFO_UINT64
1716            data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1717            data.extend_from_slice(&value.to_be_bytes());
1718            assert!(decode::<u64>(&data).is_err());
1719        }
1720
1721        // Values 24-255 must use INFO_UINT8
1722        for value in 24..=u8::MAX as u64 {
1723            // Should fail with INFO_UINT16
1724            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT16];
1725            data.extend_from_slice(&(value as u16).to_be_bytes());
1726            assert!(decode::<u64>(&data).is_err());
1727
1728            // Should fail with INFO_UINT32
1729            data = vec![MAJOR_UINT << 5 | INFO_UINT32];
1730            data.extend_from_slice(&(value as u32).to_be_bytes());
1731            assert!(decode::<u64>(&data).is_err());
1732
1733            // Should fail with INFO_UINT64
1734            data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1735            data.extend_from_slice(&value.to_be_bytes());
1736            assert!(decode::<u64>(&data).is_err());
1737        }
1738
1739        // Values 256-65535 must use INFO_UINT16
1740        for value in [(u8::MAX as u64 + 1), u16::MAX as u64] {
1741            // Should fail with INFO_UINT32
1742            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT32];
1743            data.extend_from_slice(&(value as u32).to_be_bytes());
1744            assert!(decode::<u64>(&data).is_err());
1745
1746            // Should fail with INFO_UINT64
1747            data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1748            data.extend_from_slice(&value.to_be_bytes());
1749            assert!(decode::<u64>(&data).is_err());
1750        }
1751
1752        // Values 65536-4294967295 must use INFO_UINT32
1753        for value in [(u16::MAX as u64 + 1), u32::MAX as u64] {
1754            // Should fail with INFO_UINT64
1755            let mut data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1756            data.extend_from_slice(&value.to_be_bytes());
1757            assert!(decode::<u64>(&data).is_err());
1758        }
1759    }
1760
1761    /// Tests that signed integers encode correctly across the various ranges.
1762    #[test]
1763    fn test_int_encoding() {
1764        let cases = [
1765            // Positive values use major type 0
1766            (0i64, vec![0x00]),
1767            (23i64, vec![0x17]),
1768            (24i64, vec![0x18, 0x18]),
1769            (
1770                i64::MAX,
1771                vec![0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1772            ),
1773            // Negative values use major type 1 with (-1 - n) encoding
1774            (-1i64, vec![0x20]),               // -1 -> wire value 0
1775            (-24i64, vec![0x37]),              // -24 -> wire value 23
1776            (-25i64, vec![0x38, 0x18]),        // -25 -> wire value 24
1777            (-256i64, vec![0x38, 0xff]),       // -256 -> wire value 255
1778            (-257i64, vec![0x39, 0x01, 0x00]), // -257 -> wire value 256
1779            (
1780                i64::MIN,
1781                vec![0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1782            ),
1783        ];
1784
1785        for (value, expected) in cases {
1786            assert_eq!(
1787                encode(value).unwrap(),
1788                expected,
1789                "encoding failed for value {}",
1790                value
1791            );
1792        }
1793    }
1794
1795    /// Tests that signed integers decode correctly across the various ranges.
1796    #[test]
1797    fn test_int_decoding() {
1798        let cases = [
1799            // Positive values (major type 0)
1800            (vec![0x00], 0i64),
1801            (vec![0x17], 23i64),
1802            (vec![0x18, 0x18], 24i64),
1803            (
1804                vec![0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1805                i64::MAX,
1806            ),
1807            // Negative values (major type 1)
1808            (vec![0x20], -1i64),
1809            (vec![0x37], -24i64),
1810            (vec![0x38, 0x18], -25i64),
1811            (vec![0x38, 0xff], -256i64),
1812            (vec![0x39, 0x01, 0x00], -257i64),
1813            (
1814                vec![0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
1815                i64::MIN,
1816            ),
1817        ];
1818
1819        for (data, expected) in cases {
1820            assert_eq!(
1821                decode::<i64>(&data).unwrap(),
1822                expected,
1823                "decoding failed for data {:?}",
1824                data
1825            );
1826        }
1827    }
1828
1829    /// Tests that signed integers are rejected for overflow conditions.
1830    #[test]
1831    fn test_int_rejection() {
1832        // Positive value > i64::MAX (major type 0 with value i64::MAX + 1)
1833        let mut data = vec![MAJOR_UINT << 5 | INFO_UINT64];
1834        data.extend_from_slice(&((i64::MAX as u64) + 1).to_be_bytes());
1835        let result = decode::<i64>(&data);
1836        assert!(result.is_err());
1837        match result.unwrap_err() {
1838            Error::IntegerOverflow(negative, v, max) => {
1839                assert!(!negative);
1840                assert_eq!(v, 9223372036854775808);
1841                assert_eq!(max, 9223372036854775807);
1842            }
1843            other => panic!("Expected IntegerOverflow error, got {:?}", other),
1844        }
1845
1846        // Negative value < i64::MIN (major type 1 with wire value > i64::MAX)
1847        let mut data = vec![MAJOR_NINT << 5 | INFO_UINT64];
1848        data.extend_from_slice(&((i64::MAX as u64) + 1).to_be_bytes());
1849        let result = decode::<i64>(&data);
1850        assert!(result.is_err());
1851        match result.unwrap_err() {
1852            Error::IntegerOverflow(negative, v, max) => {
1853                assert!(negative);
1854                assert_eq!(v, 9223372036854775808);
1855                assert_eq!(max, 9223372036854775807);
1856            }
1857            other => panic!("Expected IntegerOverflow error, got {:?}", other),
1858        }
1859
1860        // Non-canonical negative integer encoding
1861        let data = vec![MAJOR_NINT << 5 | INFO_UINT8, 0x10]; // -17 with INFO_UINT8
1862        let result = decode::<i64>(&data);
1863        assert!(result.is_err());
1864        match result.unwrap_err() {
1865            Error::NonCanonical => {}
1866            other => panic!("Expected NonCanonical error, got {:?}", other),
1867        }
1868    }
1869
1870    /// Tests that byte strings encode correctly on a bunch of samples.
1871    #[test]
1872    fn test_bytes_encoding() {
1873        // Empty bytes
1874        let empty: Vec<u8> = vec![];
1875        let encoded = encode(&empty).unwrap();
1876        assert_eq!(encoded, vec![0x40]); // major 2, length 0
1877
1878        // 1 byte
1879        let one_byte = vec![0xaa];
1880        let encoded = encode(&one_byte).unwrap();
1881        assert_eq!(encoded, vec![0x41, 0xaa]); // major 2, length 1, data
1882
1883        // Longer bytes
1884        let long_bytes = vec![0xde, 0xad, 0xbe, 0xef];
1885        let encoded = encode(&long_bytes).unwrap();
1886        assert_eq!(encoded, vec![0x44, 0xde, 0xad, 0xbe, 0xef]); // major 2, length 4, data
1887
1888        // Test &Vec<u8> reference
1889        let bytes_vec = vec![1, 2, 3];
1890        let bytes_vec_ref = &bytes_vec;
1891        let encoded = encode(bytes_vec_ref).unwrap();
1892        assert_eq!(encoded, vec![0x43, 1, 2, 3]);
1893
1894        // Test &[u8] slice reference
1895        let bytes_slice: &[u8] = &[4, 5, 6];
1896        let encoded = encode(bytes_slice).unwrap();
1897        assert_eq!(encoded, vec![0x43, 4, 5, 6]);
1898
1899        // Test [u8; N] fixed-size array
1900        let bytes_array: [u8; 3] = [7, 8, 9];
1901        let encoded = encode(bytes_array).unwrap();
1902        assert_eq!(encoded, vec![0x43, 7, 8, 9]);
1903
1904        // Test &[u8; N] fixed-size array reference
1905        let bytes_array_ref = &[10u8, 11, 12];
1906        let encoded = encode(bytes_array_ref).unwrap();
1907        assert_eq!(encoded, vec![0x43, 10, 11, 12]);
1908    }
1909
1910    /// Tests that byte strings decode correctly on a bunch of samples.
1911    #[test]
1912    fn test_bytes_decoding() {
1913        // Empty bytes
1914        let encoded = vec![0x40];
1915        let decoded = decode::<Vec<u8>>(&encoded).unwrap();
1916        assert_eq!(decoded, Vec::<u8>::new());
1917
1918        // 1 byte
1919        let encoded = vec![0x41, 0xaa];
1920        let decoded = decode::<Vec<u8>>(&encoded).unwrap();
1921        assert_eq!(decoded, vec![0xaa]);
1922
1923        // Longer bytes
1924        let data = vec![0xde, 0xad, 0xbe, 0xef];
1925        let mut encoded = vec![0x44]; // major 2, length 4
1926        encoded.extend_from_slice(&data);
1927        let decoded = decode::<Vec<u8>>(&encoded).unwrap();
1928        assert_eq!(decoded, data);
1929
1930        // Test fixed-size array decoding
1931        let encoded = vec![0x43, 1, 2, 3]; // major 2, length 3, data [1,2,3]
1932        let decoded = decode::<[u8; 3]>(&encoded).unwrap();
1933        assert_eq!(decoded, [1, 2, 3]);
1934
1935        // Test empty fixed-size array
1936        let encoded = vec![0x40]; // major 2, length 0
1937        let decoded = decode::<[u8; 0]>(&encoded).unwrap();
1938        assert_eq!(decoded, [0u8; 0]);
1939    }
1940
1941    /// Tests that bytes decoding fails when fixed size lengths don't match.
1942    #[test]
1943    fn test_bytes_rejection() {
1944        // Try to decode 3 bytes into a 4-byte array
1945        let encoded = vec![0x43, 1, 2, 3]; // major 2, length 3
1946        let result = decode::<[u8; 4]>(&encoded);
1947        assert!(result.is_err());
1948        match result.unwrap_err() {
1949            Error::UnexpectedItemCount(3, 4) => {} // Expected error
1950            other => panic!("Expected UnexpectedItemCount(3, 4) error, got {:?}", other),
1951        }
1952
1953        // Try to decode 4 bytes into a 2-byte array
1954        let encoded = vec![0x44, 1, 2, 3, 4]; // major 2, length 4
1955        let result = decode::<[u8; 2]>(&encoded);
1956        assert!(result.is_err());
1957        match result.unwrap_err() {
1958            Error::UnexpectedItemCount(4, 2) => {} // Expected error
1959            other => panic!("Expected UnexpectedItemCount(4, 2) error, got {:?}", other),
1960        }
1961    }
1962
1963    /// Tests that a byte-string length cannot wrap to the expected fixed size
1964    /// on 32-bit targets, including when the bytes are nested in an array.
1965    #[test]
1966    fn test_fixed_bytes_wide_length() {
1967        fn check<const N: usize>() {
1968            let bytes = [0xa5; N];
1969            let valid = encode(bytes).unwrap();
1970            assert_eq!(decode::<[u8; N]>(&valid).unwrap(), bytes);
1971
1972            let len = (1u64 << 32) + N as u64;
1973            let mut encoded = vec![0x5b];
1974            encoded.extend_from_slice(&len.to_be_bytes());
1975            encoded.extend_from_slice(&bytes);
1976            assert_eq!(
1977                decode::<[u8; N]>(&encoded),
1978                Err(Error::UnexpectedItemCount(len, N))
1979            );
1980
1981            encoded.insert(0, 0x81);
1982            assert_eq!(
1983                decode::<([u8; N],)>(&encoded),
1984                Err(Error::UnexpectedItemCount(len, N))
1985            );
1986        }
1987
1988        check::<0>();
1989        check::<1>();
1990        check::<32>();
1991    }
1992
1993    /// Tests that UTF-8 strings encode correctly on a bunch of samples.
1994    #[test]
1995    fn test_string_encoding() {
1996        // Empty string
1997        let empty = "";
1998        let encoded = encode(empty).unwrap();
1999        assert_eq!(encoded, vec![0x60]); // major 3, length 0
2000
2001        // 1 character
2002        let one_char = "a";
2003        let encoded = encode(one_char).unwrap();
2004        assert_eq!(encoded, vec![0x61, 0x61]); // major 3, length 1, 'a'
2005
2006        // Longer string
2007        let long_string = "Peter says hi!";
2008        let encoded = encode(long_string).unwrap();
2009        assert_eq!(encoded[0], 0x60 | long_string.len() as u8); // major 3, length embedded
2010        assert_eq!(&encoded[1..], long_string.as_bytes());
2011
2012        // Test String type
2013        let string_type = "Peter says hi!".to_string();
2014        let encoded = encode(&string_type).unwrap();
2015        assert_eq!(encoded[0], 0x60 | string_type.len() as u8); // major 3, length embedded
2016        assert_eq!(&encoded[1..], string_type.as_bytes());
2017
2018        // Test &String type
2019        let string_ref = &"Peter says hi!".to_string();
2020        let encoded = encode(string_ref).unwrap();
2021        assert_eq!(encoded[0], 0x60 | string_ref.len() as u8); // major 3, length embedded
2022        assert_eq!(&encoded[1..], string_ref.as_bytes());
2023    }
2024
2025    /// Tests that UTF-8 strings decode correctly on a bunch of samples.
2026    #[test]
2027    fn test_string_decoding() {
2028        // Empty string
2029        let encoded = vec![0x60];
2030        let decoded = decode::<String>(&encoded).unwrap();
2031        assert_eq!(decoded, "");
2032
2033        // 1 character
2034        let encoded = vec![0x61, 0x61];
2035        let decoded = decode::<String>(&encoded).unwrap();
2036        assert_eq!(decoded, "a");
2037
2038        // Longer string
2039        let test_str = "Peter says hi!";
2040        let mut encoded = vec![0x60 | test_str.len() as u8];
2041        encoded.extend_from_slice(test_str.as_bytes());
2042        let decoded = decode::<String>(&encoded).unwrap();
2043        assert_eq!(decoded, test_str);
2044    }
2045
2046    /// Tests that UTF-8 strings are rejected if containing invalid data.
2047    #[test]
2048    fn test_string_rejection() {
2049        // 0xff is not valid UTF-8
2050        let encoded = vec![0x61, 0xff]; // major 3, length 1, invalid byte
2051        let result = decode::<String>(&encoded);
2052        assert!(result.is_err());
2053
2054        match result.unwrap_err() {
2055            Error::InvalidUtf8 => {} // Expected error
2056            other => panic!("Expected InvalidUtf8 error, got {:?}", other),
2057        }
2058
2059        // Incomplete multi-byte sequence
2060        let encoded = vec![0x62, 0xc2, 0x00]; // major 3, length 2, incomplete UTF-8
2061        let result = decode::<String>(&encoded);
2062        assert!(result.is_err());
2063
2064        match result.unwrap_err() {
2065            Error::InvalidUtf8 => {} // Expected error
2066            other => panic!("Expected InvalidUtf8 error, got {:?}", other),
2067        }
2068    }
2069
2070    /// Tests that tuples encode correctly on a bunch of samples.
2071    #[test]
2072    fn test_tuple_encoding() {
2073        // 0-tuple
2074        let empty = ();
2075        let encoded = encode(empty).unwrap();
2076        assert_eq!(encoded, vec![0x80]); // major 4, length 0 (empty array)
2077
2078        // 1-tuple (wonky Rust syntax)
2079        let one_tuple = (42u64,);
2080        let encoded = encode(one_tuple).unwrap();
2081        assert_eq!(encoded[0], 0x81); // major 4, length 1 (array with 1 element)
2082        assert_eq!(encoded[1], 0x18); // major 0, INFO_UINT8
2083        assert_eq!(encoded[2], 42);
2084
2085        // 2-tuple
2086        let t = ("hello".to_string(), 42u64);
2087        let encoded = encode(&t).unwrap();
2088        assert_eq!(encoded[0], 0x82); // major 4, length 2 (array with 2 elements)
2089        // First element: "hello" -> 0x65 + "hello" bytes
2090        assert_eq!(encoded[1], 0x65); // major 3, length 5
2091        assert_eq!(&encoded[2..7], b"hello");
2092        // Second element: 42 -> 0x182a
2093        assert_eq!(encoded[7], 0x18); // major 0, INFO_UINT8
2094        assert_eq!(encoded[8], 42);
2095    }
2096
2097    /// Tests that tuples decode correctly on a bunch of samples.
2098    #[test]
2099    fn test_tuple_decoding() {
2100        // 0-tuple
2101        let encoded = vec![0x80]; // empty array
2102        decode::<()>(&encoded).unwrap();
2103
2104        // 1-tuple (wonky Rust syntax)
2105        let mut encoded = vec![0x81]; // array length 1
2106        encoded.extend_from_slice(&encode(42u64).unwrap()); // single element
2107        let decoded = decode::<(u64,)>(&encoded).unwrap();
2108        assert_eq!(decoded, (42u64,));
2109
2110        // 2-tuple
2111        let mut encoded = vec![0x82]; // array length 2
2112        encoded.extend_from_slice(&encode("hello".to_string()).unwrap()); // first element
2113        encoded.extend_from_slice(&encode(42u64).unwrap()); // second element
2114        let decoded = decode::<(String, u64)>(&encoded).unwrap();
2115        assert_eq!(decoded, ("hello".to_string(), 42u64));
2116    }
2117
2118    /// Tests that tuples are rejected if the size of the array does not match the
2119    /// expected size.
2120    #[test]
2121    fn test_tuple_rejection() {
2122        // Try to decode array with 1 element as 2-tuple
2123        let mut encoded = vec![0x81]; // array length 1
2124        encoded.extend_from_slice(&encode(42u64).unwrap()); // single element
2125        let result = decode::<(u64, u64)>(&encoded);
2126        assert!(result.is_err());
2127        match result.unwrap_err() {
2128            Error::UnexpectedItemCount(1, 2) => {} // Expected error
2129            other => panic!("Expected UnexpectedItemCount(1, 2) error, got {:?}", other),
2130        }
2131
2132        // Try to decode array with 3 elements as 2-tuple
2133        let mut encoded = vec![0x83]; // array length 3
2134        encoded.extend_from_slice(&encode(42u64).unwrap());
2135        encoded.extend_from_slice(&encode("test".to_string()).unwrap());
2136        encoded.extend_from_slice(&encode(vec![1u8, 2]).unwrap());
2137        let result = decode::<(u64, String)>(&encoded);
2138        assert!(result.is_err());
2139        match result.unwrap_err() {
2140            Error::UnexpectedItemCount(3, 2) => {} // Expected error
2141            other => panic!("Expected UnexpectedItemCount(3, 2) error, got {:?}", other),
2142        }
2143
2144        // Try to decode array with 1 element as empty tuple
2145        let mut encoded = vec![0x81]; // array length 1
2146        encoded.extend_from_slice(&encode(42u64).unwrap());
2147        let result = decode::<()>(&encoded);
2148        assert!(result.is_err());
2149        match result.unwrap_err() {
2150            Error::UnexpectedItemCount(1, 0) => {} // Expected error
2151            other => panic!("Expected UnexpectedItemCount(1, 0) error, got {:?}", other),
2152        }
2153    }
2154
2155    /// Test struct for array encoding/decoding with derive macros.
2156    #[derive(Debug, PartialEq, Cbor)]
2157    #[cbor(array)]
2158    struct TestArray {
2159        first: u64,
2160        second: String,
2161        third: Vec<u8>,
2162    }
2163
2164    /// Tests that array structs encode correctly in field declaration order.
2165    #[test]
2166    fn test_array_encoding() {
2167        let arr = TestArray {
2168            first: 42,
2169            second: "hello".to_string(),
2170            third: vec![1, 2, 3],
2171        };
2172        let encoded = encode(&arr).unwrap();
2173
2174        // Should be: [42, "hello", h'010203']
2175        let mut expected = vec![0x83]; // array with 3 elements
2176        expected.extend_from_slice(&encode(42u64).unwrap());
2177        expected.extend_from_slice(&encode("hello".to_string()).unwrap());
2178        expected.extend_from_slice(&encode(vec![1u8, 2, 3]).unwrap());
2179
2180        assert_eq!(encoded, expected);
2181    }
2182
2183    /// Tests that array structs decode correctly.
2184    #[test]
2185    fn test_array_decoding() {
2186        let mut data = vec![0x83]; // array with 3 elements
2187        data.extend_from_slice(&encode(100u64).unwrap());
2188        data.extend_from_slice(&encode("world".to_string()).unwrap());
2189        data.extend_from_slice(&encode(vec![4u8, 5, 6]).unwrap());
2190
2191        let decoded = decode::<TestArray>(&data).unwrap();
2192        assert_eq!(decoded.first, 100);
2193        assert_eq!(decoded.second, "world");
2194        assert_eq!(decoded.third, vec![4, 5, 6]);
2195    }
2196
2197    /// Tests that array structs are rejected if the size does not match.
2198    #[test]
2199    fn test_array_rejection() {
2200        // Too few elements (2 instead of 3)
2201        let mut data = vec![0x82]; // array with 2 elements
2202        data.extend_from_slice(&encode(42u64).unwrap());
2203        data.extend_from_slice(&encode("test".to_string()).unwrap());
2204        let result = decode::<TestArray>(&data);
2205        assert!(result.is_err());
2206        match result.unwrap_err() {
2207            Error::UnexpectedItemCount(2, 3) => {}
2208            other => panic!("Expected UnexpectedItemCount(2, 3) error, got {:?}", other),
2209        }
2210        // Too many elements (4 instead of 3)
2211        let mut data = vec![0x84]; // array with 4 elements
2212        data.extend_from_slice(&encode(42u64).unwrap());
2213        data.extend_from_slice(&encode("test".to_string()).unwrap());
2214        data.extend_from_slice(&encode(vec![1u8]).unwrap());
2215        data.extend_from_slice(&encode(42u64).unwrap());
2216        let result = decode::<TestArray>(&data);
2217        assert!(result.is_err());
2218        match result.unwrap_err() {
2219            Error::UnexpectedItemCount(4, 3) => {}
2220            other => panic!("Expected UnexpectedItemCount(4, 3) error, got {:?}", other),
2221        }
2222    }
2223
2224    /// Test struct for map encoding/decoding with derive macros.
2225    #[derive(Debug, PartialEq, Cbor)]
2226    struct TestMap {
2227        #[cbor(key = 1)]
2228        key1: u64,
2229        #[cbor(key = 2)]
2230        key2: u64,
2231        #[cbor(key = -1)]
2232        key_neg1: u64,
2233    }
2234
2235    /// Tests that maps encode correctly with deterministic key ordering.
2236    #[test]
2237    fn test_map_encoding() {
2238        // Map with positive and negative keys (should be sorted by bytewise order)
2239        let map = TestMap {
2240            key1: 42,
2241            key2: 67,
2242            key_neg1: 100,
2243        };
2244        let encoded = encode(&map).unwrap();
2245
2246        // Keys in bytewise order: 0x01, 0x02, 0x20 (1, 2, -1)
2247        assert_eq!(encoded[0], 0xa3); // map with 3 entries
2248        assert_eq!(encoded[1], 0x01); // key 1
2249        assert_eq!(encoded[2], 0x18);
2250        assert_eq!(encoded[3], 42);
2251        assert_eq!(encoded[4], 0x02); // key 2
2252        assert_eq!(encoded[5], 0x18);
2253        assert_eq!(encoded[6], 67);
2254        assert_eq!(encoded[7], 0x20); // key -1
2255        assert_eq!(encoded[8], 0x18);
2256        assert_eq!(encoded[9], 100);
2257    }
2258
2259    /// Tests that maps decode correctly.
2260    #[test]
2261    fn test_map_decoding() {
2262        // Multiple entries (in correct deterministic order)
2263        let decoded = decode::<TestMap>(&[
2264            0xa3, // map with 3 entries
2265            0x01, 0x18, 0x2a, // 1: 42
2266            0x02, 0x18, 0x43, // 2: 67
2267            0x20, 0x18, 0x64, // -1: 100
2268        ])
2269        .unwrap();
2270        assert_eq!(decoded.key1, 42);
2271        assert_eq!(decoded.key2, 67);
2272        assert_eq!(decoded.key_neg1, 100);
2273    }
2274
2275    /// Tests that maps with invalid key ordering are rejected.
2276    #[test]
2277    fn test_map_rejection() {
2278        // Keys out of order: 2 before 1
2279        let result = decode::<TestMap>(&[
2280            0xa3, // map with 3 entries
2281            0x02, 0x18, 0x43, // 2: 67 (should come after 1)
2282            0x01, 0x18, 0x2a, // 1: 42
2283            0x20, 0x18, 0x64, // -1: 100
2284        ]);
2285        assert!(result.is_err());
2286
2287        // Wrong key value
2288        let result = decode::<TestMap>(&[
2289            0xa3, // map with 3 entries
2290            0x05, 0x18, 0x2a, // 5: 42 (should be 1)
2291            0x02, 0x18, 0x43, // 2: 67
2292            0x20, 0x18, 0x64, // -1: 100
2293        ]);
2294        assert!(result.is_err());
2295    }
2296
2297    /// Test struct for map encoding/decoding with optional fields.
2298    #[derive(Debug, PartialEq, Cbor)]
2299    struct TestMapOptional {
2300        #[cbor(key = 1)]
2301        required: u64,
2302        #[cbor(key = 2)]
2303        optional1: Option<String>,
2304        #[cbor(key = 3)]
2305        nullable: Option<Option<u64>>,
2306        #[cbor(key = -1)]
2307        optional2: Option<Vec<u8>>,
2308    }
2309
2310    /// Tests that optional map fields are omitted when None during encoding,
2311    /// and that Option<Option<T>> (nullable) fields are always present.
2312    #[test]
2313    fn test_map_optional_encoding() {
2314        // All fields present (nullable with value)
2315        let map = TestMapOptional {
2316            required: 42,
2317            optional1: Some("hello".to_string()),
2318            nullable: Some(Some(1)),
2319            optional2: Some(vec![1, 2, 3]),
2320        };
2321        let encoded = encode(&map).unwrap();
2322        // Keys in bytewise order: 0x01, 0x02, 0x03, 0x20 (1, 2, 3, -1)
2323        assert_eq!(encoded[0], 0xa4); // map with 4 entries
2324        let decoded = decode::<TestMapOptional>(&encoded).unwrap();
2325        assert_eq!(decoded, map);
2326
2327        // Only required + nullable (optionals None, nullable with null value)
2328        let map = TestMapOptional {
2329            required: 42,
2330            optional1: None,
2331            nullable: Some(None),
2332            optional2: None,
2333        };
2334        let encoded = encode(&map).unwrap();
2335        assert_eq!(encoded[0], 0xa2); // map with 2 entries (required + nullable)
2336        assert_eq!(encoded, vec![0xa2, 0x01, 0x18, 42, 0x03, 0xf6]);
2337        let decoded = decode::<TestMapOptional>(&encoded).unwrap();
2338        assert_eq!(decoded, map);
2339
2340        // None and Some(None) both encode identically as null (2-state collapse)
2341        let map_none = TestMapOptional {
2342            required: 42,
2343            optional1: None,
2344            nullable: None,
2345            optional2: None,
2346        };
2347        let map_some_none = TestMapOptional {
2348            required: 42,
2349            optional1: None,
2350            nullable: Some(None),
2351            optional2: None,
2352        };
2353        assert_eq!(encode(&map_none).unwrap(), encode(&map_some_none).unwrap());
2354        // Both decode back as Some(None) since the key is always present
2355        let decoded = decode::<TestMapOptional>(&encode(&map_none).unwrap()).unwrap();
2356        assert_eq!(decoded.nullable, Some(None));
2357
2358        // One optional present, one absent (nullable always present as null)
2359        let map = TestMapOptional {
2360            required: 42,
2361            optional1: Some("hi".to_string()),
2362            nullable: Some(None),
2363            optional2: None,
2364        };
2365        let encoded = encode(&map).unwrap();
2366        assert_eq!(encoded[0], 0xa3); // map with 3 entries
2367        let decoded = decode::<TestMapOptional>(&encoded).unwrap();
2368        assert_eq!(decoded, map);
2369
2370        // Other optional present (nullable always present as null)
2371        let map = TestMapOptional {
2372            required: 42,
2373            optional1: None,
2374            nullable: Some(None),
2375            optional2: Some(vec![0xff]),
2376        };
2377        let encoded = encode(&map).unwrap();
2378        assert_eq!(encoded[0], 0xa3); // map with 3 entries
2379        let decoded = decode::<TestMapOptional>(&encoded).unwrap();
2380        assert_eq!(decoded, map);
2381    }
2382
2383    /// Tests that optional map fields decode as None when keys are missing,
2384    /// and that nullable (Option<Option<T>>) fields must always be present.
2385    #[test]
2386    fn test_map_optional_decoding() {
2387        // Decode a map with required + nullable (null value), optionals absent
2388        let decoded = decode::<TestMapOptional>(&[
2389            0xa2, // map with 2 entries
2390            0x01, 0x18, 0x2a, // 1: 42
2391            0x03, 0xf6, // 3: null
2392        ])
2393        .unwrap();
2394        assert_eq!(decoded.required, 42);
2395        assert_eq!(decoded.optional1, None);
2396        assert_eq!(decoded.nullable, Some(None));
2397        assert_eq!(decoded.optional2, None);
2398
2399        // Decode a map with required + nullable + first optional
2400        let decoded = decode::<TestMapOptional>(&[
2401            0xa3, // map with 3 entries
2402            0x01, 0x00, // 1: 0
2403            0x02, 0x62, 0x68, 0x69, // 2: "hi"
2404            0x03, 0xf6, // 3: null
2405        ])
2406        .unwrap();
2407        assert_eq!(decoded.required, 0);
2408        assert_eq!(decoded.optional1, Some("hi".to_string()));
2409        assert_eq!(decoded.nullable, Some(None));
2410        assert_eq!(decoded.optional2, None);
2411
2412        // Decode a map with required + nullable + second optional (key -1)
2413        let decoded = decode::<TestMapOptional>(&[
2414            0xa3, // map with 3 entries
2415            0x01, 0x05, // 1: 5
2416            0x03, 0xf6, // 3: null
2417            0x20, 0x41, 0xab, // -1: h'ab'
2418        ])
2419        .unwrap();
2420        assert_eq!(decoded.required, 5);
2421        assert_eq!(decoded.optional1, None);
2422        assert_eq!(decoded.nullable, Some(None));
2423        assert_eq!(decoded.optional2, Some(vec![0xab]));
2424
2425        // Decode with nullable absent must fail (it's required)
2426        let result = decode::<TestMapOptional>(&[
2427            0xa1, // map with 1 entry
2428            0x01, 0x18, 0x2a, // 1: 42 (key 3 missing)
2429        ]);
2430        assert!(result.is_err());
2431    }
2432
2433    /// Tests that maps with optional fields still reject invalid data.
2434    #[test]
2435    fn test_map_optional_rejection() {
2436        // Too many entries
2437        let result = decode::<TestMapOptional>(&[
2438            0xa5, // map with 5 entries (max is 4)
2439            0x01, 0x00, // 1: 0
2440            0x02, 0x60, // 2: ""
2441            0x03, 0xf6, // 3: null
2442            0x04, 0x00, // 4: 0 (unknown key)
2443            0x20, 0x40, // -1: h''
2444        ]);
2445        assert!(result.is_err());
2446
2447        // Required field missing (map has optional keys but not the required one)
2448        let result = decode::<TestMapOptional>(&[
2449            0xa1, // map with 1 entry
2450            0x02, 0x60, // 2: "" (key 1 is required but missing)
2451        ]);
2452        assert!(result.is_err());
2453
2454        // Nullable field missing (key 3 must always be present)
2455        let result = decode::<TestMapOptional>(&[
2456            0xa1, // map with 1 entry
2457            0x01, 0x18, 0x2a, // 1: 42 (key 3 missing)
2458        ]);
2459        assert!(result.is_err());
2460    }
2461
2462    /// Tests that Raw encodes correctly (passthrough of inner bytes).
2463    #[test]
2464    fn test_raw_encoding() {
2465        // Unsigned integer (42)
2466        let raw = Raw(vec![0x18, 0x2a]);
2467        assert_eq!(encode(&raw).unwrap(), vec![0x18, 0x2a]);
2468
2469        // String "hello"
2470        let raw = Raw(vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]);
2471        assert_eq!(
2472            encode(&raw).unwrap(),
2473            vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]
2474        );
2475
2476        // Tuple with Raw inside: ("method", <raw bytes for u64 1>)
2477        let raw = Raw(vec![0x01]);
2478        let encoded = encode(&("method", raw)).unwrap();
2479        assert_eq!(
2480            encoded,
2481            vec![
2482                0x82, // array of 2
2483                0x66, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // "method"
2484                0x01  // raw: u64 1
2485            ]
2486        );
2487    }
2488
2489    /// Tests that Raw decodes correctly (captures raw CBOR bytes).
2490    #[test]
2491    fn test_raw_decoding() {
2492        // Unsigned integer (42)
2493        let data = vec![0x18, 0x2a];
2494        let raw: Raw = decode(&data).unwrap();
2495        assert_eq!(raw.0, vec![0x18, 0x2a]);
2496
2497        // String "hello"
2498        let data = vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f];
2499        let raw: Raw = decode(&data).unwrap();
2500        assert_eq!(raw.0, vec![0x65, 0x68, 0x65, 0x6c, 0x6c, 0x6f]);
2501
2502        // Tuple with Raw: ("method", <raw params>)
2503        let data = vec![
2504            0x82, // array of 2
2505            0x66, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, // "method"
2506            0x82, 0x01, 0x63, 0x61, 0x72, 0x67, // (1, "arg")
2507        ];
2508        let (method, params): (String, Raw) = decode(&data).unwrap();
2509        assert_eq!(method, "method");
2510        assert_eq!(params.0, vec![0x82, 0x01, 0x63, 0x61, 0x72, 0x67]);
2511    }
2512
2513    /// Tests that Raw rejects unsupported major types.
2514    #[test]
2515    fn test_raw_rejection() {
2516        // Major type 6 (tags) - unsupported
2517        let data = vec![0xc0, 0x01]; // tag(0) followed by 1
2518        assert!(matches!(
2519            decode::<Raw>(&data),
2520            Err(Error::UnsupportedType(6))
2521        ));
2522
2523        // Major type 7 (floats) - unsupported, but bools/null are now supported
2524        let data = vec![0xf5]; // true - now valid
2525        assert!(decode::<Raw>(&data).is_ok());
2526
2527        // Float16 is still unsupported
2528        let data = vec![0xf9, 0x3c, 0x00]; // 1.0 as float16
2529        assert!(matches!(
2530            decode::<Raw>(&data),
2531            Err(Error::UnsupportedType(7))
2532        ));
2533
2534        // Trailing bytes
2535        let data = vec![0x18, 0x2a, 0x00]; // u64 42 + trailing 0x00
2536        assert!(matches!(decode::<Raw>(&data), Err(Error::TrailingBytes)));
2537    }
2538
2539    /// Tests that the dry-decoding verifier properly restricts the allowed types.
2540    #[test]
2541    fn test_verify() {
2542        // Valid types should pass
2543        assert!(verify(&encode(42u64).unwrap()).is_ok());
2544        assert!(verify(&encode(-42i64).unwrap()).is_ok());
2545        assert!(verify(&encode("hello").unwrap()).is_ok());
2546        assert!(verify(&encode(vec![1u8, 2, 3]).unwrap()).is_ok());
2547        assert!(verify(&encode(()).unwrap()).is_ok());
2548        assert!(verify(&encode((42u64, "test")).unwrap()).is_ok());
2549        assert!(verify(&encode((-42i64, "test")).unwrap()).is_ok());
2550        assert!(
2551            verify(
2552                &encode(&TestMap {
2553                    key1: 1,
2554                    key2: 2,
2555                    key_neg1: 3,
2556                })
2557                .unwrap()
2558            )
2559            .is_ok()
2560        );
2561
2562        // Large integers are valid at verify time (overflow is checked at decode)
2563        let mut large_uint = vec![MAJOR_UINT << 5 | INFO_UINT64];
2564        large_uint.extend_from_slice(&u64::MAX.to_be_bytes());
2565        assert!(verify(&large_uint).is_ok());
2566
2567        let mut large_nint = vec![MAJOR_NINT << 5 | INFO_UINT64];
2568        large_nint.extend_from_slice(&u64::MAX.to_be_bytes());
2569        assert!(verify(&large_nint).is_ok());
2570
2571        // Trailing bytes
2572        let mut bad_data = encode(42u64).unwrap();
2573        bad_data.push(0x00);
2574        assert!(verify(&bad_data).is_err());
2575        match verify(&bad_data).unwrap_err() {
2576            Error::TrailingBytes => {}
2577            other => panic!("Expected TrailingBytes error, got {:?}", other),
2578        }
2579
2580        // Maps with string keys are rejected (key decoding fails)
2581        let map_str_key = vec![0xa1, 0x61, 0x61, 0x61, 0x62]; // {"a": "b"}
2582        assert!(verify(&map_str_key).is_err());
2583        match verify(&map_str_key).unwrap_err() {
2584            Error::InvalidMajorType(3, 0) => {} // text key when expecting int
2585            other => panic!(
2586                "Expected InvalidMajorType error for string key, got {:?}",
2587                other
2588            ),
2589        }
2590
2591        // Major type 6 (tags) - unsupported
2592        let tagged_data = vec![
2593            0xc0, 0x74, 0x32, 0x30, 0x31, 0x33, 0x2d, 0x30, 0x33, 0x2d, 0x32, 0x31, 0x54, 0x32,
2594            0x30, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x5a,
2595        ]; // tag 0 datetime
2596        assert!(verify(&tagged_data).is_err());
2597        match verify(&tagged_data).unwrap_err() {
2598            Error::UnsupportedType(6) => {}
2599            other => panic!("Expected UnsupportedType(6) error, got {:?}", other),
2600        }
2601
2602        // Booleans and null are now supported
2603        assert!(verify(&encode(false).unwrap()).is_ok());
2604        assert!(verify(&encode(true).unwrap()).is_ok());
2605        assert!(verify(&encode(None::<u64>).unwrap()).is_ok());
2606
2607        // undefined (0xf7) is still unsupported
2608        let undefined_val = vec![0xf7];
2609        assert!(verify(&undefined_val).is_err());
2610        match verify(&undefined_val).unwrap_err() {
2611            Error::UnsupportedType(7) => {}
2612            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
2613        }
2614
2615        // Float16
2616        let float16 = vec![0xf9, 0x3c, 0x00]; // 1.0 as float16
2617        assert!(verify(&float16).is_err());
2618        match verify(&float16).unwrap_err() {
2619            Error::UnsupportedType(7) => {}
2620            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
2621        }
2622
2623        // Float32
2624        let float32 = vec![0xfa, 0x3f, 0x80, 0x00, 0x00]; // 1.0 as float32
2625        assert!(verify(&float32).is_err());
2626        match verify(&float32).unwrap_err() {
2627            Error::UnsupportedType(7) => {}
2628            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
2629        }
2630
2631        // Float64
2632        let float64 = vec![0xfb, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; // 1.0 as float64
2633        assert!(verify(&float64).is_err());
2634        match verify(&float64).unwrap_err() {
2635            Error::UnsupportedType(7) => {}
2636            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
2637        }
2638
2639        // Invalid UTF-8 in text string
2640        let invalid_text = vec![0x61, 0xff]; // text string with invalid UTF-8
2641        assert!(verify(&invalid_text).is_err());
2642        match verify(&invalid_text).unwrap_err() {
2643            Error::InvalidUtf8 => {}
2644            other => panic!("Expected InvalidUtf8 error, got {:?}", other),
2645        }
2646
2647        // Non-canonical encodings
2648        let non_canonical = vec![0x18, 0x10]; // 16 encoded as INFO_UINT8 instead of direct
2649        assert!(verify(&non_canonical).is_err());
2650        match verify(&non_canonical).unwrap_err() {
2651            Error::NonCanonical => {}
2652            other => panic!("Expected NonCanonical error, got {:?}", other),
2653        }
2654
2655        // Nested arrays with booleans are now valid
2656        let nested_bool = vec![0x81, 0xf4]; // [false]
2657        assert!(verify(&nested_bool).is_ok());
2658
2659        // Nested arrays with floats are still invalid
2660        let nested_float = vec![0x81, 0xf9, 0x3c, 0x00]; // [1.0 as float16]
2661        assert!(verify(&nested_float).is_err());
2662        match verify(&nested_float).unwrap_err() {
2663            Error::UnsupportedType(7) => {}
2664            other => panic!("Expected UnsupportedType(7) error, got {:?}", other),
2665        }
2666
2667        // Incomplete data
2668        let incomplete = vec![0x61]; // text string header without data
2669        assert!(verify(&incomplete).is_err());
2670        match verify(&incomplete).unwrap_err() {
2671            Error::UnexpectedEof => {}
2672            other => panic!("Expected UnexpectedEof error, got {:?}", other),
2673        }
2674
2675        // Invalid additional info
2676        let invalid_info = vec![0x1c]; // UINT with additional info 28 (reserved)
2677        assert!(verify(&invalid_info).is_err());
2678        match verify(&invalid_info).unwrap_err() {
2679            Error::InvalidAdditionalInfo(28) => {}
2680            other => panic!("Expected InvalidAdditionalInfo(28) error, got {:?}", other),
2681        }
2682    }
2683
2684    /// Tests that verification preserves the full array/map count on 32-bit
2685    /// targets instead of accepting only the low 32 bits' worth of items.
2686    #[test]
2687    fn test_verify_wide_container_length() {
2688        for major in [MAJOR_ARRAY, MAJOR_MAP] {
2689            for count in [0u8, 1, 3] {
2690                let mut payload = Vec::new();
2691                for item in 0..count {
2692                    payload.push(item);
2693                    if major == MAJOR_MAP {
2694                        payload.push(0xf6);
2695                    }
2696                }
2697
2698                let mut valid = vec![major << 5 | count];
2699                valid.extend_from_slice(&payload);
2700                assert_eq!(verify(&valid), Ok(()));
2701
2702                let len = (1u64 << 32) + u64::from(count);
2703                let mut encoded = vec![major << 5 | INFO_UINT64];
2704                encoded.extend_from_slice(&len.to_be_bytes());
2705                encoded.extend_from_slice(&payload);
2706                assert_eq!(verify(&encoded), Err(Error::UnexpectedEof));
2707            }
2708        }
2709    }
2710
2711    /// Tests a length overflow caught by the fuzzer, fixed in
2712    /// <https://github.com/dark-bio/crypto-rs/pull/3>.
2713    #[test]
2714    fn test_issue_3() {
2715        let encoded = vec![123, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
2716        let result = decode::<String>(&encoded);
2717        assert!(result.is_err());
2718    }
2719
2720    /// Struct used for embed tests.
2721    #[derive(Debug, Clone, PartialEq, Cbor)]
2722    struct Inner {
2723        #[cbor(key = 1)]
2724        a: u64,
2725        #[cbor(key = 2)]
2726        b: String,
2727    }
2728
2729    /// Equivalent of embedded struct for byte-identity comparison.
2730    #[derive(Debug, PartialEq, Cbor)]
2731    struct Flat {
2732        #[cbor(key = 1)]
2733        a: u64,
2734        #[cbor(key = 2)]
2735        b: String,
2736        #[cbor(key = 3)]
2737        c: u64,
2738    }
2739
2740    /// Tests that an embedded struct produces identical CBOR to a flat struct
2741    /// with the same fields and keys.
2742    #[test]
2743    fn test_map_embed_flat() {
2744        #[derive(Debug, PartialEq, Cbor)]
2745        struct Embedded {
2746            #[cbor(embed)]
2747            inner: Inner,
2748            #[cbor(key = 3)]
2749            c: u64,
2750        }
2751        let embedded = Embedded {
2752            inner: Inner {
2753                a: 1,
2754                b: "two".to_string(),
2755            },
2756            c: 3,
2757        };
2758        let flat = Flat {
2759            a: 1,
2760            b: "two".to_string(),
2761            c: 3,
2762        };
2763        assert_eq!(encode(&embedded).unwrap(), encode(&flat).unwrap());
2764
2765        // Decode back
2766        let decoded = decode::<Embedded>(&encode(&embedded).unwrap()).unwrap();
2767        assert_eq!(decoded, embedded);
2768    }
2769
2770    /// Tests that embedded fields are correctly sorted with direct fields.
2771    #[test]
2772    fn test_map_embed_key_order() {
2773        // Embed field has keys 1,2 and direct field has key -1 (sorts after positives)
2774        #[derive(Debug, PartialEq, Cbor)]
2775        struct WithNeg {
2776            #[cbor(embed)]
2777            inner: Inner,
2778            #[cbor(key = -1)]
2779            neg: u64,
2780        }
2781        let val = WithNeg {
2782            inner: Inner {
2783                a: 10,
2784                b: "hi".to_string(),
2785            },
2786            neg: 99,
2787        };
2788        let data = encode(&val).unwrap();
2789        // Keys should be sorted: 1, 2, -1
2790        assert_eq!(data[0], 0xa3); // map with 3 entries
2791        let decoded = decode::<WithNeg>(&data).unwrap();
2792        assert_eq!(decoded, val);
2793    }
2794
2795    /// Tests that an embedded struct with optional fields works correctly.
2796    #[test]
2797    fn test_map_embed_optional() {
2798        #[derive(Debug, Clone, PartialEq, Cbor)]
2799        struct OptInner {
2800            #[cbor(key = 1)]
2801            id: u64,
2802            #[cbor(key = 2)]
2803            extra: Option<Vec<u8>>,
2804        }
2805        #[derive(Debug, PartialEq, Cbor)]
2806        struct Outer {
2807            #[cbor(embed)]
2808            base: OptInner,
2809            #[cbor(key = 3)]
2810            name: String,
2811        }
2812        // With optional present
2813        let val = Outer {
2814            base: OptInner {
2815                id: 42,
2816                extra: Some(vec![0xab]),
2817            },
2818            name: "test".to_string(),
2819        };
2820        let data = encode(&val).unwrap();
2821        assert_eq!(data[0], 0xa3); // 3 entries
2822        let decoded = decode::<Outer>(&data).unwrap();
2823        assert_eq!(decoded, val);
2824
2825        // Without optional
2826        let val = Outer {
2827            base: OptInner {
2828                id: 42,
2829                extra: None,
2830            },
2831            name: "test".to_string(),
2832        };
2833        let data = encode(&val).unwrap();
2834        assert_eq!(data[0], 0xa2); // 2 entries
2835        let decoded = decode::<Outer>(&data).unwrap();
2836        assert_eq!(decoded, val);
2837    }
2838
2839    /// Tests that duplicate keys between direct and embed fields are detected
2840    /// during encoding (the embed merge returns an error on collision).
2841    #[test]
2842    fn test_map_embed_duplicate_key_encode() {
2843        #[derive(Debug, PartialEq, Cbor)]
2844        struct Clash {
2845            #[cbor(key = 1)] // same key as Inner.a
2846            x: u64,
2847            #[cbor(embed)]
2848            inner: Inner,
2849        }
2850        let val = Clash {
2851            x: 99,
2852            inner: Inner {
2853                a: 1,
2854                b: "hi".to_string(),
2855            },
2856        };
2857        // Encoding a struct with overlapping direct + embed keys returns an error.
2858        match encode(&val) {
2859            Err(Error::DuplicateMapKey(1)) => {}
2860            other => panic!("expected Err(DuplicateMapKey(1)), got {:?}", other),
2861        }
2862    }
2863
2864    /// Tests that duplicate keys between direct and embed fields are detected
2865    /// during decoding when receiving hand-crafted CBOR with a collision.
2866    #[test]
2867    fn test_map_embed_duplicate_key_decode() {
2868        #[derive(Debug, PartialEq, Cbor)]
2869        struct Clash {
2870            #[cbor(key = 1)] // same key as Inner.a
2871            x: u64,
2872            #[cbor(embed)]
2873            inner: Inner,
2874        }
2875        // Hand-craft CBOR: {1: 99, 2: "hi"}, where key 1 collides between direct
2876        // field x and embed field inner.a. Decode must reject with DuplicateMapKey.
2877        let mut enc = Encoder::new();
2878        enc.encode_map_header(2);
2879        enc.encode_int(1);
2880        enc.encode_uint(99);
2881        enc.encode_int(2);
2882        enc.extend(&encode("hi".to_string()).unwrap());
2883        let data = enc.finish();
2884        match decode::<Clash>(&data) {
2885            Err(Error::DuplicateMapKey(1)) => {}
2886            other => panic!("expected DuplicateMapKey(1), got {:?}", other),
2887        }
2888    }
2889
2890    /// Tests that multiple embedded structs round-trip correctly: two embeds
2891    /// with non-overlapping key ranges plus a direct field.
2892    #[test]
2893    fn test_map_embed_multiple() {
2894        #[derive(Debug, Clone, PartialEq, Cbor)]
2895        struct EmbedA {
2896            #[cbor(key = 1)]
2897            a: u64,
2898            #[cbor(key = 2)]
2899            b: String,
2900        }
2901        #[derive(Debug, Clone, PartialEq, Cbor)]
2902        struct EmbedB {
2903            #[cbor(key = 3)]
2904            c: Vec<u8>,
2905            #[cbor(key = 4)]
2906            d: u64,
2907        }
2908        #[derive(Debug, PartialEq, Cbor)]
2909        struct Multi {
2910            #[cbor(embed)]
2911            first: EmbedA,
2912            #[cbor(embed)]
2913            second: EmbedB,
2914            #[cbor(key = -1)]
2915            extra: String,
2916        }
2917        let val = Multi {
2918            first: EmbedA {
2919                a: 10,
2920                b: "hello".to_string(),
2921            },
2922            second: EmbedB {
2923                c: vec![0xDE, 0xAD],
2924                d: 42,
2925            },
2926            extra: "world".to_string(),
2927        };
2928        let data = encode(&val).unwrap();
2929        // All 5 keys should be present: 1, 2, 3, 4, -1
2930        assert_eq!(data[0], 0xa5); // map with 5 entries
2931        let decoded = decode::<Multi>(&data).unwrap();
2932        assert_eq!(decoded, val);
2933    }
2934
2935    /// Tests that nested embeds (an embed containing another embed) work.
2936    #[test]
2937    fn test_map_embed_nested() {
2938        #[derive(Debug, Clone, PartialEq, Cbor)]
2939        struct Base {
2940            #[cbor(key = 1)]
2941            x: u64,
2942        }
2943        #[derive(Debug, Clone, PartialEq, Cbor)]
2944        struct Mid {
2945            #[cbor(embed)]
2946            base: Base,
2947            #[cbor(key = 2)]
2948            y: String,
2949        }
2950        #[derive(Debug, PartialEq, Cbor)]
2951        struct Top {
2952            #[cbor(embed)]
2953            mid: Mid,
2954            #[cbor(key = 3)]
2955            z: u64,
2956        }
2957        let val = Top {
2958            mid: Mid {
2959                base: Base { x: 1 },
2960                y: "two".to_string(),
2961            },
2962            z: 3,
2963        };
2964        let data = encode(&val).unwrap();
2965        assert_eq!(data[0], 0xa3); // 3 entries
2966        let decoded = decode::<Top>(&data).unwrap();
2967        assert_eq!(decoded, val);
2968    }
2969
2970    /// Tests mixed positive/negative embed keys decode correctly.
2971    #[test]
2972    fn test_map_embed_mixed_sign_keys_decode() {
2973        #[derive(Debug, Clone, PartialEq, Cbor)]
2974        struct SignedInner {
2975            #[cbor(key = 1)]
2976            pos: u64,
2977            #[cbor(key = -1)]
2978            neg: u64,
2979        }
2980        #[derive(Debug, PartialEq, Cbor)]
2981        struct SignedOuter {
2982            #[cbor(embed)]
2983            inner: SignedInner,
2984            #[cbor(key = 2)]
2985            c: u64,
2986        }
2987        let val = SignedOuter {
2988            inner: SignedInner { pos: 11, neg: 22 },
2989            c: 33,
2990        };
2991        let data = encode(&val).unwrap();
2992        let decoded = decode::<SignedOuter>(&data).unwrap();
2993        assert_eq!(decoded, val);
2994    }
2995
2996    /// Tests that overlapping keys between two embeds are detected on decode.
2997    #[test]
2998    fn test_map_embed_embed_collision() {
2999        #[derive(Debug, Clone, PartialEq, Cbor)]
3000        struct Left {
3001            #[cbor(key = 1)]
3002            a: u64,
3003            #[cbor(key = 2)]
3004            b: u64,
3005        }
3006        #[derive(Debug, Clone, PartialEq, Cbor)]
3007        struct Right {
3008            #[cbor(key = 2)] // collides with Left.b
3009            c: u64,
3010            #[cbor(key = 3)]
3011            d: u64,
3012        }
3013        #[derive(Debug, PartialEq, Cbor)]
3014        struct Both {
3015            #[cbor(embed)]
3016            left: Left,
3017            #[cbor(embed)]
3018            right: Right,
3019        }
3020        // Hand-craft CBOR with keys 1, 2, 3 (no wire-level duplicate, but
3021        // embeds Left and Right both claim key 2).
3022        let mut enc = Encoder::new();
3023        enc.encode_map_header(3);
3024        enc.encode_int(1);
3025        enc.encode_uint(10);
3026        enc.encode_int(2);
3027        enc.encode_uint(20);
3028        enc.encode_int(3);
3029        enc.encode_uint(30);
3030        let data = enc.finish();
3031        match decode::<Both>(&data) {
3032            Err(Error::DuplicateMapKey(2)) => {}
3033            other => panic!("expected DuplicateMapKey(2), got {:?}", other),
3034        }
3035    }
3036
3037    /// Tests that unknown keys in the wire data are rejected during decode.
3038    #[test]
3039    fn test_map_embed_unknown_key() {
3040        // Hand-craft CBOR: {1: 1, 2: "two", 3: 3, 99: 0} where key 99 is
3041        // not claimed by any direct field or embed.
3042        #[derive(Debug, PartialEq, Cbor)]
3043        struct Embedded {
3044            #[cbor(embed)]
3045            inner: Inner,
3046            #[cbor(key = 3)]
3047            c: u64,
3048        }
3049        let mut enc = Encoder::new();
3050        enc.encode_map_header(4);
3051        enc.encode_int(1);
3052        enc.encode_uint(1);
3053        enc.encode_int(2);
3054        enc.extend(&encode("two".to_string()).unwrap());
3055        enc.encode_int(3);
3056        enc.encode_uint(3);
3057        enc.encode_int(99);
3058        enc.encode_uint(0);
3059        let data = enc.finish();
3060        match decode::<Embedded>(&data) {
3061            Err(Error::DecodeFailed(msg)) if msg.contains("unknown") => {}
3062            other => panic!("expected DecodeFailed with 'unknown', got {:?}", other),
3063        }
3064    }
3065
3066    /// Tests that out-of-order keys in wire data are rejected during embed decode.
3067    #[test]
3068    fn test_map_embed_key_order_rejected() {
3069        #[derive(Debug, PartialEq, Cbor)]
3070        struct Embedded {
3071            #[cbor(embed)]
3072            inner: Inner,
3073            #[cbor(key = 3)]
3074            c: u64,
3075        }
3076        // Hand-craft CBOR with keys out of order: {2: "x", 1: 1, 3: 3}
3077        let mut enc = Encoder::new();
3078        enc.encode_map_header(3);
3079        enc.encode_int(2);
3080        enc.extend(&encode("x".to_string()).unwrap());
3081        enc.encode_int(1);
3082        enc.encode_uint(1);
3083        enc.encode_int(3);
3084        enc.encode_uint(3);
3085        let data = enc.finish();
3086        match decode::<Embedded>(&data) {
3087            Err(Error::InvalidMapKeyOrder(1, 2)) => {}
3088            other => panic!("expected InvalidMapKeyOrder(1, 2), got {:?}", other),
3089        }
3090    }
3091
3092    /// Tests that wire-level duplicate keys are rejected during embed decode.
3093    #[test]
3094    fn test_map_embed_wire_duplicate_key() {
3095        #[derive(Debug, PartialEq, Cbor)]
3096        struct Embedded {
3097            #[cbor(embed)]
3098            inner: Inner,
3099            #[cbor(key = 3)]
3100            c: u64,
3101        }
3102        // Hand-craft CBOR with duplicate key 1: {1: 1, 1: 2, 2: "x", 3: 3}
3103        let mut enc = Encoder::new();
3104        enc.encode_map_header(4);
3105        enc.encode_int(1);
3106        enc.encode_uint(1);
3107        enc.encode_int(1);
3108        enc.encode_uint(2);
3109        enc.encode_int(2);
3110        enc.extend(&encode("x".to_string()).unwrap());
3111        enc.encode_int(3);
3112        enc.encode_uint(3);
3113        let data = enc.finish();
3114        match decode::<Embedded>(&data) {
3115            Err(Error::DuplicateMapKey(1)) => {}
3116            other => panic!("expected DuplicateMapKey(1), got {:?}", other),
3117        }
3118    }
3119
3120    /// Tests that schema-level collision between an optional direct field and
3121    /// an embed field is caught on encode even when the optional is None.
3122    #[test]
3123    fn test_map_embed_optional_overlap_encode() {
3124        #[derive(Debug, Clone, PartialEq, Cbor)]
3125        struct EmbedInner {
3126            #[cbor(key = 1)]
3127            a: u64,
3128        }
3129        #[derive(Debug, PartialEq, Cbor)]
3130        struct Broken {
3131            #[cbor(key = 1)]
3132            x: Option<u64>, // collides with EmbedInner.a
3133            #[cbor(embed)]
3134            inner: EmbedInner,
3135        }
3136        match encode(&Broken {
3137            x: None,
3138            inner: EmbedInner { a: 42 },
3139        }) {
3140            Err(Error::DuplicateMapKey(1)) => {}
3141            other => panic!("expected Err(DuplicateMapKey(1)), got {:?}", other),
3142        }
3143    }
3144
3145    /// Tests that embed encoding validates actual merged keys too, not only
3146    /// keys reported by the embed's schema declaration.
3147    #[test]
3148    fn test_map_embed_runtime_key_mismatch_rejected() {
3149        #[derive(Debug, Clone, PartialEq)]
3150        struct RogueEmbed;
3151
3152        impl MapEncode for RogueEmbed {
3153            fn encode_map(&self, enc: &mut MapEncodeBuffer) -> Result<(), Error> {
3154                enc.push(1i64, &7u64)?;
3155                Ok(())
3156            }
3157        }
3158
3159        impl MapDecode for RogueEmbed {
3160            fn cbor_map_keys() -> &'static [i64] {
3161                // Intentionally dishonest: claims key 2.
3162                &[2]
3163            }
3164
3165            fn decode_map<'a, E: MapEntryAccess<'a>>(entries: &mut E) -> Result<Self, Error> {
3166                let _ = entries.take(2);
3167                Ok(Self)
3168            }
3169        }
3170
3171        #[derive(Debug, PartialEq, Cbor)]
3172        struct Parent {
3173            #[cbor(key = 1)]
3174            x: u64,
3175            #[cbor(embed)]
3176            rogue: RogueEmbed,
3177        }
3178
3179        match encode(&Parent {
3180            x: 42,
3181            rogue: RogueEmbed,
3182        }) {
3183            Err(Error::DuplicateMapKey(1)) => {}
3184            other => panic!("expected Err(DuplicateMapKey(1)), got {:?}", other),
3185        }
3186    }
3187
3188    /// Tests that an optional embed (Option<T> with #[cbor(embed)]) produces
3189    /// the correct CBOR: Some → all fields present, None → all fields absent.
3190    #[test]
3191    fn test_map_embed_optional_roundtrip() {
3192        #[derive(Debug, PartialEq, Cbor)]
3193        struct Embedded {
3194            #[cbor(embed)]
3195            inner: Option<Inner>,
3196            #[cbor(key = 3)]
3197            c: u64,
3198        }
3199        // Non-nil: all fields present
3200        let original = Embedded {
3201            inner: Some(Inner {
3202                a: 1,
3203                b: "two".to_string(),
3204            }),
3205            c: 3,
3206        };
3207        let data = encode(&original).unwrap();
3208        assert_eq!(data[0], 0xa3); // map with 3 entries
3209        let decoded = decode::<Embedded>(&data).unwrap();
3210        assert_eq!(decoded, original);
3211
3212        // Byte identity with flat struct
3213        let flat = Flat {
3214            a: 1,
3215            b: "two".to_string(),
3216            c: 3,
3217        };
3218        assert_eq!(data, encode(&flat).unwrap());
3219
3220        // Nil: only direct field present
3221        let nil_original = Embedded { inner: None, c: 3 };
3222        let data = encode(&nil_original).unwrap();
3223        assert_eq!(data[0], 0xa1); // map with 1 entry (only key 3)
3224        let decoded = decode::<Embedded>(&data).unwrap();
3225        assert_eq!(decoded, nil_original);
3226        assert_eq!(decoded.inner, None);
3227        assert_eq!(decoded.c, 3);
3228    }
3229
3230    /// Tests that a partial optional embed (some required keys present but not
3231    /// all) is rejected during decode, per the all-or-none semantics.
3232    #[test]
3233    fn test_map_embed_optional_partial_rejected() {
3234        #[derive(Debug, PartialEq, Cbor)]
3235        struct Outer {
3236            #[cbor(embed)]
3237            inner: Option<Inner>,
3238            #[cbor(key = 3)]
3239            c: u64,
3240        }
3241        // Hand-craft: {1: 42, 3: 7}, key 1 present (from Inner) but key 2 missing
3242        let mut enc = Encoder::new();
3243        enc.encode_map_header(2);
3244        enc.encode_int(1);
3245        enc.encode_uint(42);
3246        enc.encode_int(3);
3247        enc.encode_uint(7);
3248        let data = enc.finish();
3249        match decode::<Outer>(&data) {
3250            Err(Error::DecodeFailed(msg)) if msg.contains("missing required key 2") => {}
3251            other => panic!("expected DecodeFailed about missing key 2, got {:?}", other),
3252        }
3253    }
3254
3255    /// Tests that an optional embed with optional inner fields works correctly.
3256    /// All combinations: full Some, Some with inner optional absent, None.
3257    #[test]
3258    fn test_map_embed_optional_with_optional_fields() {
3259        #[derive(Debug, Clone, PartialEq, Cbor)]
3260        struct OptInner {
3261            #[cbor(key = 1)]
3262            a: u64,
3263            #[cbor(key = 2)]
3264            b: Option<Vec<u8>>,
3265        }
3266        #[derive(Debug, PartialEq, Cbor)]
3267        struct Outer {
3268            #[cbor(embed)]
3269            inner: Option<OptInner>,
3270            #[cbor(key = 3)]
3271            c: u64,
3272        }
3273        // All present: inner has both required and optional field
3274        let original = Outer {
3275            inner: Some(OptInner {
3276                a: 42,
3277                b: Some(vec![0xab]),
3278            }),
3279            c: 7,
3280        };
3281        let data = encode(&original).unwrap();
3282        assert_eq!(data[0], 0xa3); // map(3)
3283        let decoded = decode::<Outer>(&data).unwrap();
3284        assert_eq!(decoded, original);
3285
3286        // Mandatory key present, optional key omitted
3287        let partial = Outer {
3288            inner: Some(OptInner { a: 42, b: None }),
3289            c: 7,
3290        };
3291        let data = encode(&partial).unwrap();
3292        assert_eq!(data[0], 0xa2); // map(2): keys 1 and 3
3293        let decoded = decode::<Outer>(&data).unwrap();
3294        assert_eq!(decoded, partial);
3295
3296        // Nil: all embed fields absent
3297        let nil = Outer { inner: None, c: 7 };
3298        let data = encode(&nil).unwrap();
3299        assert_eq!(data[0], 0xa1); // map(1): only key 3
3300        let decoded = decode::<Outer>(&data).unwrap();
3301        assert_eq!(decoded, nil);
3302    }
3303
3304    /// Tests that a mandatory value embed nested inside an optional embed
3305    /// enforces all-or-none: either all keys from the optional embed
3306    /// (including its sub-embed) are present, or none.
3307    #[test]
3308    fn test_map_embed_optional_nested_all_or_none() {
3309        #[derive(Debug, Clone, PartialEq, Cbor)]
3310        struct Sub {
3311            #[cbor(key = 1)]
3312            x: u64,
3313        }
3314        #[derive(Debug, Clone, PartialEq, Cbor)]
3315        struct Mid {
3316            #[cbor(embed)]
3317            sub: Sub,
3318            #[cbor(key = 2)]
3319            y: u64,
3320        }
3321        #[derive(Debug, PartialEq, Cbor)]
3322        struct Outer {
3323            #[cbor(embed)]
3324            mid: Option<Mid>,
3325            #[cbor(key = 3)]
3326            z: u64,
3327        }
3328        // All present: round-trip
3329        let original = Outer {
3330            mid: Some(Mid {
3331                sub: Sub { x: 1 },
3332                y: 2,
3333            }),
3334            z: 3,
3335        };
3336        let data = encode(&original).unwrap();
3337        assert_eq!(data[0], 0xa3); // map(3)
3338        let decoded = decode::<Outer>(&data).unwrap();
3339        assert_eq!(decoded, original);
3340
3341        // None present: only Z
3342        let nil = Outer { mid: None, z: 3 };
3343        let data = encode(&nil).unwrap();
3344        assert_eq!(data[0], 0xa1); // map(1)
3345        let decoded = decode::<Outer>(&data).unwrap();
3346        assert_eq!(decoded, nil);
3347
3348        // Partial: only key 1 (X from Sub) but not key 2 (Y), rejected
3349        let mut enc = Encoder::new();
3350        enc.encode_map_header(2);
3351        enc.encode_int(1);
3352        enc.encode_uint(1);
3353        enc.encode_int(3);
3354        enc.encode_uint(3);
3355        match decode::<Outer>(&enc.finish()) {
3356            Err(Error::DecodeFailed(msg)) if msg.contains("missing required key 2") => {}
3357            other => panic!("expected DecodeFailed about missing key 2, got {:?}", other),
3358        }
3359    }
3360
3361    /// Tests nested optional embeds: Option<A> where A optionally embeds
3362    /// Option<B>. Activity in B propagates to A, so missing required keys
3363    /// in A are rejected when B's keys are present.
3364    #[test]
3365    fn test_map_embed_nested_optional_propagation() {
3366        #[derive(Debug, Clone, PartialEq, Cbor)]
3367        struct B {
3368            #[cbor(key = 2)]
3369            y: u64,
3370        }
3371        #[derive(Debug, Clone, PartialEq, Cbor)]
3372        struct A {
3373            #[cbor(key = 1)]
3374            x: u64,
3375            #[cbor(embed)]
3376            b: Option<B>,
3377        }
3378        #[derive(Debug, PartialEq, Cbor)]
3379        struct O {
3380            #[cbor(embed)]
3381            a: Option<A>,
3382            #[cbor(key = 3)]
3383            z: u64,
3384        }
3385        // All present: round-trip
3386        let original = O {
3387            a: Some(A {
3388                x: 1,
3389                b: Some(B { y: 2 }),
3390            }),
3391            z: 3,
3392        };
3393        let data = encode(&original).unwrap();
3394        let decoded = decode::<O>(&data).unwrap();
3395        assert_eq!(decoded, original);
3396
3397        // Both optional embeds nil: only Z present
3398        let nil_all = O { a: None, z: 3 };
3399        let data = encode(&nil_all).unwrap();
3400        let decoded = decode::<O>(&data).unwrap();
3401        assert_eq!(decoded, nil_all);
3402
3403        // Outer active, inner nil: X present, Y absent; valid
3404        let outer_only = O {
3405            a: Some(A { x: 1, b: None }),
3406            z: 3,
3407        };
3408        let data = encode(&outer_only).unwrap();
3409        let decoded = decode::<O>(&data).unwrap();
3410        assert_eq!(decoded, outer_only);
3411        assert!(decoded.a.as_ref().unwrap().b.is_none());
3412
3413        // Bug case: inner key present (Y from B), outer key missing (X from A).
3414        // Wire {2: 2, 3: 3} must fail, since B's activity propagates to A, making
3415        // X required. This is the Go TestMapEmbedNestedPointerAllOrNone
3416        // "inner-active-outer-missing" case.
3417        let mut enc = Encoder::new();
3418        enc.encode_map_header(2);
3419        enc.encode_int(2);
3420        enc.encode_uint(2);
3421        enc.encode_int(3);
3422        enc.encode_uint(3);
3423        match decode::<O>(&enc.finish()) {
3424            Err(Error::DecodeFailed(msg)) if msg.contains("missing required key 1") => {}
3425            other => panic!("expected DecodeFailed about missing key 1, got {:?}", other),
3426        }
3427    }
3428
3429    /// Tests that out-of-order keys in an optional embed produce
3430    /// InvalidMapKeyOrder (consistent with mandatory embed error semantics).
3431    #[test]
3432    fn test_map_embed_optional_key_order_rejected() {
3433        #[derive(Debug, PartialEq, Cbor)]
3434        struct Outer {
3435            #[cbor(embed)]
3436            inner: Option<Inner>,
3437            #[cbor(key = 3)]
3438            c: u64,
3439        }
3440        // Wire: {2: "x", 1: 42, 3: 7} (keys 2,1 out of order)
3441        let mut enc = Encoder::new();
3442        enc.encode_map_header(3);
3443        enc.encode_int(2);
3444        enc.encode_field(&"x".to_string()).unwrap();
3445        enc.encode_int(1);
3446        enc.encode_uint(42);
3447        enc.encode_int(3);
3448        enc.encode_uint(7);
3449        match decode::<Outer>(&enc.finish()) {
3450            Err(Error::InvalidMapKeyOrder(1, 2)) => {}
3451            other => panic!("expected InvalidMapKeyOrder(1, 2), got {:?}", other),
3452        }
3453    }
3454
3455    /// Tests that schema-level collision between a direct field and an optional
3456    /// embed field is caught on encode even when the embed is None.
3457    #[test]
3458    fn test_map_embed_optional_direct_collision() {
3459        #[derive(Debug, PartialEq, Cbor)]
3460        struct Clash {
3461            #[cbor(key = 1)] // same key as Inner.a
3462            x: u64,
3463            #[cbor(embed)]
3464            inner: Option<Inner>,
3465        }
3466        // Even with None, the schema check catches the collision
3467        match encode(&Clash { x: 99, inner: None }) {
3468            Err(Error::DuplicateMapKey(1)) => {}
3469            other => panic!("expected Err(DuplicateMapKey(1)), got {:?}", other),
3470        }
3471    }
3472
3473    /// Tests that duplicate keys between two embeds (one optional) are detected.
3474    #[test]
3475    fn test_map_embed_optional_embed_collision() {
3476        #[derive(Debug, Clone, PartialEq, Cbor)]
3477        struct Left {
3478            #[cbor(key = 1)]
3479            a: u64,
3480            #[cbor(key = 2)]
3481            b: u64,
3482        }
3483        #[derive(Debug, Clone, PartialEq, Cbor)]
3484        struct Right {
3485            #[cbor(key = 2)] // collides with Left.b
3486            c: u64,
3487            #[cbor(key = 3)]
3488            d: u64,
3489        }
3490        #[derive(Debug, PartialEq, Cbor)]
3491        struct Both {
3492            #[cbor(embed)]
3493            left: Option<Left>,
3494            #[cbor(embed)]
3495            right: Option<Right>,
3496        }
3497        // Hand-craft CBOR with keys 1, 2, 3
3498        let mut enc = Encoder::new();
3499        enc.encode_map_header(3);
3500        enc.encode_int(1);
3501        enc.encode_uint(10);
3502        enc.encode_int(2);
3503        enc.encode_uint(20);
3504        enc.encode_int(3);
3505        enc.encode_uint(30);
3506        match decode::<Both>(&enc.finish()) {
3507            Err(Error::DuplicateMapKey(2)) => {}
3508            other => panic!("expected DuplicateMapKey(2), got {:?}", other),
3509        }
3510    }
3511
3512    /// Tests that unknown keys in wire data are rejected even when the struct
3513    /// has optional embeds.
3514    #[test]
3515    fn test_map_embed_optional_unknown_key() {
3516        #[derive(Debug, PartialEq, Cbor)]
3517        struct Outer {
3518            #[cbor(embed)]
3519            inner: Option<Inner>,
3520            #[cbor(key = 3)]
3521            c: u64,
3522        }
3523        // Wire: {1: 1, 2: "two", 3: 3, 99: 0} (key 99 unknown)
3524        let mut enc = Encoder::new();
3525        enc.encode_map_header(4);
3526        enc.encode_int(1);
3527        enc.encode_uint(1);
3528        enc.encode_int(2);
3529        enc.encode_field(&"two".to_string()).unwrap();
3530        enc.encode_int(3);
3531        enc.encode_uint(3);
3532        enc.encode_int(99);
3533        enc.encode_uint(0);
3534        match decode::<Outer>(&enc.finish()) {
3535            Err(Error::DecodeFailed(msg)) if msg.contains("unknown") => {}
3536            other => panic!("expected DecodeFailed with 'unknown', got {:?}", other),
3537        }
3538    }
3539
3540    /// Tests wire-level duplicate keys are rejected when decoding optional embeds.
3541    #[test]
3542    fn test_map_embed_optional_wire_duplicate_key() {
3543        #[derive(Debug, PartialEq, Cbor)]
3544        struct Outer {
3545            #[cbor(embed)]
3546            inner: Option<Inner>,
3547            #[cbor(key = 3)]
3548            c: u64,
3549        }
3550        // Hand-craft CBOR: {1: 1, 1: 2, 2: "x", 3: 3} (duplicate key 1)
3551        let mut enc = Encoder::new();
3552        enc.encode_map_header(4);
3553        enc.encode_int(1);
3554        enc.encode_uint(1);
3555        enc.encode_int(1);
3556        enc.encode_uint(2);
3557        enc.encode_int(2);
3558        enc.encode_field(&"x".to_string()).unwrap();
3559        enc.encode_int(3);
3560        enc.encode_uint(3);
3561        match decode::<Outer>(&enc.finish()) {
3562            Err(Error::DuplicateMapKey(1)) => {}
3563            other => panic!("expected DuplicateMapKey(1), got {:?}", other),
3564        }
3565    }
3566
3567    /// Tests multiple optional embeds with non-overlapping keys.
3568    #[test]
3569    fn test_map_embed_optional_multiple() {
3570        #[derive(Debug, Clone, PartialEq, Cbor)]
3571        struct EmbedA {
3572            #[cbor(key = 1)]
3573            a: u64,
3574        }
3575        #[derive(Debug, Clone, PartialEq, Cbor)]
3576        struct EmbedB {
3577            #[cbor(key = 2)]
3578            b: String,
3579        }
3580        #[derive(Debug, PartialEq, Cbor)]
3581        struct Multi {
3582            #[cbor(embed)]
3583            first: Option<EmbedA>,
3584            #[cbor(embed)]
3585            second: Option<EmbedB>,
3586            #[cbor(key = 3)]
3587            c: u64,
3588        }
3589        // Both present
3590        let val = Multi {
3591            first: Some(EmbedA { a: 1 }),
3592            second: Some(EmbedB {
3593                b: "two".to_string(),
3594            }),
3595            c: 3,
3596        };
3597        let data = encode(&val).unwrap();
3598        assert_eq!(data[0], 0xa3); // 3 entries
3599        let decoded = decode::<Multi>(&data).unwrap();
3600        assert_eq!(decoded, val);
3601
3602        // First present, second absent
3603        let val = Multi {
3604            first: Some(EmbedA { a: 1 }),
3605            second: None,
3606            c: 3,
3607        };
3608        let data = encode(&val).unwrap();
3609        assert_eq!(data[0], 0xa2); // 2 entries
3610        let decoded = decode::<Multi>(&data).unwrap();
3611        assert_eq!(decoded, val);
3612
3613        // First absent, second present
3614        let val = Multi {
3615            first: None,
3616            second: Some(EmbedB {
3617                b: "two".to_string(),
3618            }),
3619            c: 3,
3620        };
3621        let data = encode(&val).unwrap();
3622        assert_eq!(data[0], 0xa2); // 2 entries
3623        let decoded = decode::<Multi>(&data).unwrap();
3624        assert_eq!(decoded, val);
3625
3626        // Both absent
3627        let val = Multi {
3628            first: None,
3629            second: None,
3630            c: 3,
3631        };
3632        let data = encode(&val).unwrap();
3633        assert_eq!(data[0], 0xa1); // 1 entry
3634        let decoded = decode::<Multi>(&data).unwrap();
3635        assert_eq!(decoded, val);
3636    }
3637
3638    /// Tests that mixing mandatory and optional embeds works correctly.
3639    #[test]
3640    fn test_map_embed_mixed_mandatory_optional() {
3641        #[derive(Debug, Clone, PartialEq, Cbor)]
3642        struct Required {
3643            #[cbor(key = 1)]
3644            a: u64,
3645        }
3646        #[derive(Debug, Clone, PartialEq, Cbor)]
3647        struct OptionalPart {
3648            #[cbor(key = 2)]
3649            b: String,
3650        }
3651        #[derive(Debug, PartialEq, Cbor)]
3652        struct Mixed {
3653            #[cbor(embed)]
3654            required: Required,
3655            #[cbor(embed)]
3656            optional: Option<OptionalPart>,
3657            #[cbor(key = 3)]
3658            c: u64,
3659        }
3660        // Both embeds present
3661        let val = Mixed {
3662            required: Required { a: 1 },
3663            optional: Some(OptionalPart {
3664                b: "two".to_string(),
3665            }),
3666            c: 3,
3667        };
3668        let data = encode(&val).unwrap();
3669        assert_eq!(data[0], 0xa3);
3670        let decoded = decode::<Mixed>(&data).unwrap();
3671        assert_eq!(decoded, val);
3672
3673        // Optional absent, mandatory present
3674        let val = Mixed {
3675            required: Required { a: 1 },
3676            optional: None,
3677            c: 3,
3678        };
3679        let data = encode(&val).unwrap();
3680        assert_eq!(data[0], 0xa2);
3681        let decoded = decode::<Mixed>(&data).unwrap();
3682        assert_eq!(decoded, val);
3683
3684        // Wire missing mandatory embed's key but optional present → error
3685        let mut enc = Encoder::new();
3686        enc.encode_map_header(2);
3687        enc.encode_int(2);
3688        enc.encode_field(&"hello".to_string()).unwrap();
3689        enc.encode_int(3);
3690        enc.encode_uint(3);
3691        match decode::<Mixed>(&enc.finish()) {
3692            Err(Error::DecodeFailed(msg)) if msg.contains("missing required key 1") => {}
3693            other => panic!("expected DecodeFailed about missing key 1, got {:?}", other),
3694        }
3695    }
3696
3697    /// Tests that an optional embed where all inner fields are themselves
3698    /// optional correctly round-trips as None when all inner fields are absent.
3699    /// When none of the embed's keys appear on the wire, the embed is None,
3700    /// NOT Some(AllOptional { ... all None ... }).
3701    #[test]
3702    fn test_map_embed_optional_all_inner_optional() {
3703        #[derive(Debug, Clone, PartialEq, Cbor)]
3704        struct AllOpt {
3705            #[cbor(key = 1)]
3706            a: Option<u64>,
3707            #[cbor(key = 2)]
3708            b: Option<Vec<u8>>,
3709        }
3710        #[derive(Debug, PartialEq, Cbor)]
3711        struct Outer {
3712            #[cbor(embed)]
3713            opt: Option<AllOpt>,
3714            #[cbor(key = 3)]
3715            c: u64,
3716        }
3717        // All absent: encode Some(AllOpt { None, None }) → only key 3 on wire
3718        // Decode back → None (indistinguishable from outer None)
3719        let val = Outer {
3720            opt: Some(AllOpt { a: None, b: None }),
3721            c: 7,
3722        };
3723        let data = encode(&val).unwrap();
3724        assert_eq!(data[0], 0xa1); // map(1): only key 3
3725        let decoded = decode::<Outer>(&data).unwrap();
3726        assert_eq!(decoded.c, 7);
3727        assert_eq!(decoded.opt, None); // round-trips as None, not Some({None, None})
3728
3729        // One inner field present: embed is Some
3730        let val = Outer {
3731            opt: Some(AllOpt {
3732                a: Some(42),
3733                b: None,
3734            }),
3735            c: 7,
3736        };
3737        let data = encode(&val).unwrap();
3738        assert_eq!(data[0], 0xa2); // map(2): keys 1 and 3
3739        let decoded = decode::<Outer>(&data).unwrap();
3740        assert_eq!(decoded, val);
3741    }
3742
3743    /// Tests the entry helper functions round-trip correctly.
3744    #[test]
3745    fn test_map_entries_roundtrip() {
3746        let original = TestMap {
3747            key1: 42,
3748            key2: 67,
3749            key_neg1: 100,
3750        };
3751        let data = encode(&original).unwrap();
3752        let entries = decode_map_entries(&data).unwrap();
3753        assert_eq!(entries.len(), 3);
3754        assert_eq!(entries[0].0, 1);
3755        assert_eq!(entries[1].0, 2);
3756        assert_eq!(entries[2].0, -1);
3757
3758        let re_encoded = encode_map_entries(&entries);
3759        assert_eq!(data, re_encoded);
3760    }
3761
3762    /// Tests that decode_map_entries rejects out-of-order and duplicate keys.
3763    #[test]
3764    fn test_map_entries_rejection() {
3765        // Out-of-order keys: 2 before 1.
3766        let mut enc = Encoder::new();
3767        enc.encode_map_header(2);
3768        enc.encode_int(2);
3769        enc.encode_uint(67);
3770        enc.encode_int(1);
3771        enc.encode_uint(42);
3772        match decode_map_entries(&enc.finish()) {
3773            Err(Error::InvalidMapKeyOrder(1, 2)) => {}
3774            other => panic!("expected InvalidMapKeyOrder(1, 2), got {:?}", other),
3775        }
3776
3777        // Duplicate keys: 1 appears twice.
3778        let mut enc = Encoder::new();
3779        enc.encode_map_header(2);
3780        enc.encode_int(1);
3781        enc.encode_uint(1);
3782        enc.encode_int(1);
3783        enc.encode_uint(2);
3784        match decode_map_entries(&enc.finish()) {
3785            Err(Error::DuplicateMapKey(1)) => {}
3786            other => panic!("expected DuplicateMapKey(1), got {:?}", other),
3787        }
3788    }
3789
3790    /// Tests that deeply nested CBOR structures are rejected with an error
3791    /// instead of causing a stack overflow, but nesting up to the maximum
3792    /// depth is still accepted.
3793    #[test]
3794    fn test_max_nesting_depth() {
3795        let mut at_limit = vec![0x81u8; MAX_DEPTH - 1];
3796        at_limit.push(0x00);
3797        assert!(verify(&at_limit).is_ok());
3798
3799        let mut over_limit = vec![0x81u8; MAX_DEPTH + 1];
3800        over_limit.push(0x00);
3801        assert_eq!(verify(&over_limit), Err(Error::MaxDepthExceeded(MAX_DEPTH)));
3802    }
3803
3804    /// Tests that Array<T> encodes correctly as a CBOR array of individually
3805    /// encoded items.
3806    #[test]
3807    fn test_generic_array_encoding() {
3808        // Empty array
3809        assert_eq!(encode(Array::<u64>(vec![])).unwrap(), vec![0x80]);
3810
3811        // Array of unsigned integers
3812        assert_eq!(
3813            encode(Array(vec![1u64, 2, 3])).unwrap(),
3814            vec![0x83, 0x01, 0x02, 0x03]
3815        );
3816
3817        // Array of strings round-trips correctly
3818        let strings = Array(vec!["hello".to_string(), "world".to_string()]);
3819        let encoded = encode(&strings).unwrap();
3820        let decoded = decode::<Array<String>>(&encoded).unwrap();
3821        assert_eq!(decoded.0, vec!["hello", "world"]);
3822    }
3823
3824    /// Tests that Array<T> decodes correctly from CBOR arrays.
3825    #[test]
3826    fn test_generic_array_decoding() {
3827        // Empty array
3828        let arr = decode::<Array<u64>>(&[0x80]).unwrap();
3829        assert!(arr.0.is_empty());
3830
3831        // Array of unsigned integers
3832        let arr = decode::<Array<u64>>(&[0x83, 0x01, 0x02, 0x03]).unwrap();
3833        assert_eq!(arr.0, vec![1, 2, 3]);
3834
3835        // Trailing bytes should fail
3836        assert!(decode::<Array<u64>>(&[0x80, 0x00]).is_err());
3837
3838        // Nested types: array of tuples
3839        let nested = Array(vec![(1u64, "a".to_string()), (2u64, "b".to_string())]);
3840        let encoded = encode(&nested).unwrap();
3841        let decoded = decode::<Array<(u64, String)>>(&encoded).unwrap();
3842        assert_eq!(nested, decoded);
3843
3844        // As a struct field
3845        #[derive(Cbor, Debug, PartialEq)]
3846        struct WithArray {
3847            #[cbor(key = 1)]
3848            items: Array<u64>,
3849            #[cbor(key = 2)]
3850            name: String,
3851        }
3852        let original = WithArray {
3853            items: Array(vec![10, 20, 30]),
3854            name: "test".to_string(),
3855        };
3856        let encoded = encode(&original).unwrap();
3857        let decoded = decode::<WithArray>(&encoded).unwrap();
3858        assert_eq!(original, decoded);
3859    }
3860
3861    /// Tests that FixedArray<T, N> encodes correctly as a CBOR array of exactly
3862    /// N individually encoded items.
3863    #[test]
3864    fn test_fixed_array_encoding() {
3865        // Empty fixed array
3866        assert_eq!(encode(FixedArray::<u64, 0>([])).unwrap(), vec![0x80]);
3867
3868        // Fixed array of unsigned integers
3869        assert_eq!(
3870            encode(FixedArray([1u64, 2, 3])).unwrap(),
3871            vec![0x83, 0x01, 0x02, 0x03]
3872        );
3873
3874        // Fixed array of strings round-trips correctly
3875        let strings = FixedArray(["hello".to_string(), "world".to_string()]);
3876        let encoded = encode(&strings).unwrap();
3877        let decoded = decode::<FixedArray<String, 2>>(&encoded).unwrap();
3878        assert_eq!(decoded.0, ["hello", "world"]);
3879    }
3880
3881    /// Tests that FixedArray<T, N> decodes correctly from CBOR arrays and rejects
3882    /// length mismatches.
3883    #[test]
3884    fn test_fixed_array_decoding() {
3885        // Empty fixed array
3886        let arr = decode::<FixedArray<u64, 0>>(&[0x80]).unwrap();
3887        assert_eq!(arr.0, [0u64; 0]);
3888
3889        // Fixed array of unsigned integers
3890        let arr = decode::<FixedArray<u64, 3>>(&[0x83, 0x01, 0x02, 0x03]).unwrap();
3891        assert_eq!(arr.0, [1, 2, 3]);
3892
3893        // Trailing bytes should fail
3894        assert!(decode::<FixedArray<u64, 0>>(&[0x80, 0x00]).is_err());
3895
3896        // Wrong length should fail (too many)
3897        let result = decode::<FixedArray<u64, 2>>(&[0x83, 0x01, 0x02, 0x03]);
3898        assert!(result.is_err());
3899        match result.unwrap_err() {
3900            Error::UnexpectedItemCount(3, 2) => {}
3901            e => panic!("expected UnexpectedItemCount, got {:?}", e),
3902        }
3903
3904        // Wrong length should fail (too few)
3905        let result = decode::<FixedArray<u64, 4>>(&[0x83, 0x01, 0x02, 0x03]);
3906        assert!(result.is_err());
3907        match result.unwrap_err() {
3908            Error::UnexpectedItemCount(3, 4) => {}
3909            e => panic!("expected UnexpectedItemCount, got {:?}", e),
3910        }
3911
3912        // Nested types: fixed array of tuples
3913        let nested = FixedArray([(1u64, "a".to_string()), (2u64, "b".to_string())]);
3914        let encoded = encode(&nested).unwrap();
3915        let decoded = decode::<FixedArray<(u64, String), 2>>(&encoded).unwrap();
3916        assert_eq!(nested, decoded);
3917
3918        // As a struct field
3919        #[derive(Cbor, Debug, PartialEq)]
3920        struct WithFixedArray {
3921            #[cbor(key = 1)]
3922            items: FixedArray<u64, 3>,
3923            #[cbor(key = 2)]
3924            name: String,
3925        }
3926        let original = WithFixedArray {
3927            items: FixedArray([10, 20, 30]),
3928            name: "test".to_string(),
3929        };
3930        let encoded = encode(&original).unwrap();
3931        let decoded = decode::<WithFixedArray>(&encoded).unwrap();
3932        assert_eq!(original, decoded);
3933    }
3934}