Skip to main content

c2pa_cbor/
lib.rs

1// Copyright 2026 Adobe. All rights reserved.
2// This file is licensed to you under the Apache License,
3// Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
4// or the MIT license (http://opensource.org/licenses/MIT),
5// at your option.
6
7// Unless required by applicable law or agreed to in writing,
8// this software is distributed on an "AS IS" BASIS, WITHOUT
9// WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or
10// implied. See the LICENSE-MIT and LICENSE-APACHE files for the
11// specific language governing permissions and limitations under
12// each license.
13
14// Portions derived from serde_cbor (https://github.com/pyfisch/cbor)
15
16//! # C2PA CBOR Library
17//!
18//! A CBOR (Concise Binary Object Representation) encoder/decoder with support for tagged types.
19//!
20//! ## Architecture
21//!
22//! This library uses a **dual-path serialization strategy** for optimal performance:
23//!
24//! - **Fast path**: When collection sizes are known at compile time (the common case),
25//!   data is written directly to the output with zero buffering overhead.
26//! - **Buffering path**: When sizes are unknown (e.g., `#[serde(flatten)]` in `serde_transcode`),
27//!   entries are buffered in memory and written as definite-length once the count is known.
28//!
29//! This design maintains C2PA's requirement for deterministic, definite-length encoding
30//! while supporting the full serde data model including complex features like flatten.
31//!
32//! ## Features
33//! - Full support for CBOR major types 0-7
34//! - Tagged types (major type 6) including:
35//!   - Date/time strings (tag 0)
36//!   - Epoch timestamps (tag 1)
37//!   - URIs (tag 32)
38//!   - Base64url encoded data (tag 33)
39//!   - Base64 encoded data (tag 34)
40//!   - RFC 8746 typed arrays (tags 64-87):
41//!     - Unsigned integer arrays (uint8, uint16, uint32, uint64) in big-endian and little-endian
42//!     - Signed integer arrays (sint8, sint16, sint32, sint64) in big-endian and little-endian
43//!     - Floating point arrays (float16, float32, float64, float128) in big-endian and little-endian
44//! - Custom tag support via `write_tag()` and `read_tag()` methods
45//!
46//! ## Performance
47//! Binary byte arrays are efficiently encoded/decoded with minimal overhead:
48//! - Use `serde_bytes::ByteBuf` or `#[serde(with = "serde_bytes")]` for optimal byte array performance
49//! - Byte strings are written as raw bytes (1 header byte + length encoding + data)
50//! - 1KB byte array: 3 bytes overhead (header + 2-byte length)
51//! - 100KB byte array: 5 bytes overhead (header + 4-byte length)
52//! - No allocations during encoding; single allocation during decoding
53//!
54//! ### Speed Characteristics (on typical hardware)
55//! - **Encoding**: ~30-35 GB/s for large arrays (virtually memcpy speed)
56//! - **Decoding**: ~24-29 GB/s for large arrays
57//! - Small arrays (1KB): ~160ns encode, ~270ns decode
58//! - Large arrays (1MB): ~30µs encode, ~41µs decode
59//! - Performance scales linearly with data size
60//! - Zero-copy design means encoding is just a memcpy after writing the header
61//!
62//! ## Example
63//! ```rust
64//! use c2pa_cbor::{encode_datetime_string, encode_uint8_array, encode_uri, from_slice};
65//! use serde_bytes::ByteBuf;
66//!
67//! // Encode a URI with tag 32
68//! let mut buf = Vec::new();
69//! encode_uri(&mut buf, "https://example.com").unwrap();
70//! let decoded: String = from_slice(&buf).unwrap();
71//! assert_eq!(decoded, "https://example.com");
72//!
73//! // Encode a typed array with tag 64 (efficient with serde_bytes)
74//! let data = ByteBuf::from(vec![1, 2, 3, 4, 5]);
75//! let mut buf2 = Vec::new();
76//! let mut encoder = c2pa_cbor::Encoder::new(&mut buf2);
77//! encoder.write_tag(64).unwrap();
78//! encoder.encode(&data).unwrap();
79//! ```
80
81// Internal constants module (not part of public API)
82mod constants;
83
84pub mod error;
85pub use error::{Error, Result};
86
87pub mod encoder;
88pub use encoder::{Encoder, to_vec, to_writer};
89
90pub mod decoder;
91// Re-export DOS protection constants for user configuration
92pub use constants::{DEFAULT_MAX_ALLOCATION, DEFAULT_MAX_DEPTH};
93pub use decoder::{
94    Decoder, from_reader, from_reader_with_limit, from_slice, from_slice_with_limit,
95};
96
97pub mod value;
98pub use value::{Value, from_value, to_value};
99
100pub mod tags;
101pub use tags::*;
102
103/// Serialization module for compatibility with serde_cbor
104pub mod ser;
105
106/// Deserialization module for compatibility with serde_cbor
107pub mod de {
108    pub use crate::Decoder as Deserializer;
109}
110
111/// Type alias for `Encoder` (serde_cbor compatibility)
112pub type Serializer<W> = Encoder<W>;
113/// Type alias for `Decoder` (serde_cbor compatibility)
114pub type Deserializer<R> = Decoder<R>;
115
116// Example usage and tests
117#[cfg(test)]
118mod tests {
119    use std::collections::HashMap;
120
121    use serde::{Deserialize, Serialize};
122
123    use super::*;
124    use crate::constants::*;
125
126    #[derive(Debug, Serialize, Deserialize, PartialEq)]
127    struct Person {
128        name: String,
129        age: u32,
130        emails: Vec<String>,
131    }
132
133    #[test]
134    fn test_basic_types() {
135        assert_eq!(from_slice::<u32>(&to_vec(&42u32).unwrap()).unwrap(), 42);
136        assert_eq!(from_slice::<i32>(&to_vec(&-42i32).unwrap()).unwrap(), -42);
137        assert!(from_slice::<bool>(&to_vec(&true).unwrap()).unwrap());
138        assert_eq!(
139            from_slice::<String>(&to_vec(&"hello".to_string()).unwrap()).unwrap(),
140            "hello"
141        );
142    }
143
144    #[test]
145    fn test_struct() {
146        let person = Person {
147            name: "Alice".to_string(),
148            age: 30,
149            emails: vec!["alice@example.com".to_string()],
150        };
151        let encoded = to_vec(&person).unwrap();
152        let decoded: Person = from_slice(&encoded).unwrap();
153        assert_eq!(person, decoded);
154    }
155
156    #[test]
157    fn test_map() {
158        let mut map = HashMap::new();
159        map.insert("key1".to_string(), 100);
160        map.insert("key2".to_string(), 200);
161        let encoded = to_vec(&map).unwrap();
162        let decoded: HashMap<String, i32> = from_slice(&encoded).unwrap();
163        assert_eq!(map, decoded);
164    }
165
166    #[test]
167    fn test_tagged_datetime_string() {
168        let mut buf = Vec::new();
169        encode_datetime_string(&mut buf, "2024-01-15T10:30:00Z").unwrap();
170
171        // Verify the tag is encoded correctly
172        // Tag 0 with small value is encoded as 0xC0 (major type 6, value 0)
173        assert_eq!(buf[0], 0xc0);
174
175        // Decode the tagged value - it should deserialize the content (the string)
176        let decoded: String = from_slice(&buf).unwrap();
177        assert_eq!(decoded, "2024-01-15T10:30:00Z");
178    }
179
180    #[test]
181    fn test_tagged_epoch_datetime() {
182        let mut buf = Vec::new();
183        let epoch: i64 = 1705315800; // Some epoch timestamp
184        encode_epoch_datetime(&mut buf, epoch).unwrap();
185
186        // Tag 1 is encoded as 0xC1 (major type 6, value 1)
187        assert_eq!(buf[0], 0xc1);
188
189        // Decode the tagged value
190        let decoded: i64 = from_slice(&buf).unwrap();
191        assert_eq!(decoded, epoch);
192    }
193
194    #[test]
195    fn test_tagged_uri() {
196        let mut buf = Vec::new();
197        encode_uri(&mut buf, "https://example.com/path").unwrap();
198
199        // Tag 32 is encoded as 0xD8 0x20 (major type 6, additional info 24, value 32)
200        assert_eq!(buf[0], 0xd8);
201        assert_eq!(buf[1], 32);
202
203        // Decode the tagged value
204        let decoded: String = from_slice(&buf).unwrap();
205        assert_eq!(decoded, "https://example.com/path");
206    }
207
208    #[test]
209    fn test_tagged_base64url() {
210        let mut buf = Vec::new();
211        encode_base64url(&mut buf, "SGVsbG8gV29ybGQ").unwrap();
212
213        // Tag 33 is encoded as 0xD8 0x21
214        assert_eq!(buf[0], 0xd8);
215        assert_eq!(buf[1], 33);
216
217        let decoded: String = from_slice(&buf).unwrap();
218        assert_eq!(decoded, "SGVsbG8gV29ybGQ");
219    }
220
221    #[test]
222    fn test_manual_tag_encoding() {
223        let mut buf = Vec::new();
224        let mut encoder = Encoder::new(&mut buf);
225
226        // Manually encode a custom tag (e.g., tag 100) with a string value
227        encoder.write_tag(100).unwrap();
228        encoder.encode(&"custom tagged value").unwrap();
229
230        // Tag 100 is encoded as 0xD8 0x64
231        assert_eq!(buf[0], 0xd8);
232        assert_eq!(buf[1], 100);
233
234        // Decode should give us the string content
235        let decoded: String = from_slice(&buf).unwrap();
236        assert_eq!(decoded, "custom tagged value");
237    }
238
239    #[test]
240    fn test_read_tag_method() {
241        let mut buf = Vec::new();
242        let mut encoder = Encoder::new(&mut buf);
243        encoder.write_tag(42).unwrap();
244        encoder.encode(&"test").unwrap();
245
246        let mut decoder = Decoder::new(&buf[..]);
247        let tag = decoder.read_tag().unwrap();
248        assert_eq!(tag, 42);
249
250        // After reading the tag, we can decode the content
251        let content: String = decoder.decode().unwrap();
252        assert_eq!(content, "test");
253    }
254
255    #[test]
256    fn test_typed_array_uint8() {
257        let mut buf = Vec::new();
258        let data: [u8; 5] = [1, 2, 3, 4, 5];
259        encode_uint8_array(&mut buf, &data).unwrap();
260
261        // Tag 64 is encoded as 0xD8 0x40
262        assert_eq!(buf[0], 0xd8);
263        assert_eq!(buf[1], 64);
264
265        // Decode as byte array
266        let decoded: Vec<u8> = from_slice(&buf).unwrap();
267        assert_eq!(decoded, vec![1, 2, 3, 4, 5]);
268    }
269
270    #[test]
271    fn test_typed_array_uint16be() {
272        let mut buf = Vec::new();
273        let data: [u16; 3] = [0x1234, 0x5678, 0x9abc];
274        encode_uint16be_array(&mut buf, &data).unwrap();
275
276        // Tag 65 is encoded as 0xD8 0x41
277        assert_eq!(buf[0], 0xd8);
278        assert_eq!(buf[1], 65);
279
280        // Decode as byte array
281        let decoded: Vec<u8> = from_slice(&buf).unwrap();
282        // Should be big-endian encoded
283        assert_eq!(decoded, vec![0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc]);
284    }
285
286    #[test]
287    fn test_typed_array_uint32be() {
288        let mut buf = Vec::new();
289        let data: [u32; 2] = [0x12345678, 0x9abcdef0];
290        encode_uint32be_array(&mut buf, &data).unwrap();
291
292        // Tag 66 is encoded as 0xD8 0x42
293        assert_eq!(buf[0], 0xd8);
294        assert_eq!(buf[1], 66);
295
296        let decoded: Vec<u8> = from_slice(&buf).unwrap();
297        assert_eq!(
298            decoded,
299            vec![0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0]
300        );
301    }
302
303    #[test]
304    fn test_typed_array_uint64be() {
305        let mut buf = Vec::new();
306        let data: [u64; 1] = [0x123456789abcdef0];
307        encode_uint64be_array(&mut buf, &data).unwrap();
308
309        // Tag 67 is encoded as 0xD8 0x43
310        assert_eq!(buf[0], 0xd8);
311        assert_eq!(buf[1], 67);
312
313        let decoded: Vec<u8> = from_slice(&buf).unwrap();
314        assert_eq!(
315            decoded,
316            vec![0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0]
317        );
318    }
319
320    #[test]
321    fn test_typed_array_float32be() {
322        let mut buf = Vec::new();
323        let data: [f32; 2] = [1.5, 2.5];
324        encode_float32be_array(&mut buf, &data).unwrap();
325
326        // Tag 81 is encoded as 0xD8 0x51
327        assert_eq!(buf[0], 0xd8);
328        assert_eq!(buf[1], 81);
329
330        let decoded: Vec<u8> = from_slice(&buf).unwrap();
331        // Verify we have the right number of bytes (2 floats * 4 bytes each)
332        assert_eq!(decoded.len(), 8);
333    }
334
335    #[test]
336    fn test_typed_array_float64be() {
337        let mut buf = Vec::new();
338        let data: [f64; 2] = [1.5, 2.5];
339        encode_float64be_array(&mut buf, &data).unwrap();
340
341        // Tag 82 is encoded as 0xD8 0x52
342        assert_eq!(buf[0], 0xd8);
343        assert_eq!(buf[1], 82);
344
345        let decoded: Vec<u8> = from_slice(&buf).unwrap();
346        // Verify we have the right number of bytes (2 floats * 8 bytes each)
347        assert_eq!(decoded.len(), 16);
348    }
349
350    #[test]
351    fn test_typed_array_uint16le() {
352        let mut buf = Vec::new();
353        let data: [u16; 3] = [0x1234, 0x5678, 0x9abc];
354        encode_uint16le_array(&mut buf, &data).unwrap();
355
356        // Tag 69 is encoded as 0xD8 0x45
357        assert_eq!(buf[0], 0xd8);
358        assert_eq!(buf[1], 69);
359
360        let decoded: Vec<u8> = from_slice(&buf).unwrap();
361        // Should be little-endian encoded
362        assert_eq!(decoded, vec![0x34, 0x12, 0x78, 0x56, 0xbc, 0x9a]);
363    }
364
365    #[test]
366    fn test_large_byte_array_performance() {
367        use serde_bytes::ByteBuf;
368
369        // Test that large byte arrays are efficiently encoded/decoded with serde_bytes
370        // CBOR byte arrays should be: 1 byte header + length encoding + raw bytes
371
372        // 1KB array
373        let data: Vec<u8> = (0..1024).map(|i| (i % 256) as u8).collect();
374        let byte_buf = ByteBuf::from(data.clone());
375        let encoded = to_vec(&byte_buf).unwrap();
376
377        // Overhead should be minimal: 1 byte major type + 2 bytes for length (1024 = 0x400)
378        assert_eq!(encoded.len(), 1024 + 3); // 3 bytes overhead
379        assert_eq!(encoded[0], (MAJOR_BYTES << 5) | 25); // 25 = two-byte length follows
380        assert_eq!(encoded[1], 0x04); // high byte of 1024
381        assert_eq!(encoded[2], 0x00); // low byte of 1024
382
383        let decoded: ByteBuf = from_slice(&encoded).unwrap();
384        assert_eq!(decoded.into_vec(), data);
385
386        // Test 100KB array
387        let large_data: Vec<u8> = (0..102400).map(|i| (i % 256) as u8).collect();
388        let large_byte_buf = ByteBuf::from(large_data.clone());
389        let encoded_large = to_vec(&large_byte_buf).unwrap();
390
391        // Overhead for 102400 bytes: 1 byte major + 4 bytes for length
392        assert_eq!(encoded_large.len(), 102400 + 5);
393
394        let decoded_large: ByteBuf = from_slice(&encoded_large).unwrap();
395        assert_eq!(decoded_large.into_vec(), large_data);
396    }
397
398    #[test]
399    fn test_byte_array_zero_copy_encoding() {
400        use serde_bytes::ByteBuf;
401
402        // Verify that byte arrays are written directly without transformation
403        let data: Vec<u8> = vec![0x42, 0xff, 0x00, 0xaa, 0x55];
404        let byte_buf = ByteBuf::from(data.clone());
405        let encoded = to_vec(&byte_buf).unwrap();
406
407        // Should be: major type byte + length + raw data
408        assert_eq!(encoded[0], (MAJOR_BYTES << 5) | 5); // length 5 embedded
409        assert_eq!(&encoded[1..], &[0x42, 0xff, 0x00, 0xaa, 0x55]);
410
411        let decoded: ByteBuf = from_slice(&encoded).unwrap();
412        assert_eq!(decoded.into_vec(), data);
413    }
414
415    #[test]
416    fn test_vec_u8_as_array() {
417        // Without serde_bytes, Vec<u8> serializes as an array
418        let data: Vec<u8> = vec![1, 2, 3];
419        let encoded = to_vec(&data).unwrap();
420
421        // First byte should be array type with length 3
422        assert_eq!(encoded[0], (MAJOR_ARRAY << 5) | 3);
423
424        let decoded: Vec<u8> = from_slice(&encoded).unwrap();
425        assert_eq!(decoded, data);
426    }
427
428    #[test]
429    fn test_serde_bytes_efficiency() {
430        use serde_bytes::ByteBuf;
431
432        // Compare encoding efficiency: Vec<u8> vs serde_bytes::ByteBuf
433        let data: Vec<u8> = vec![1, 2, 3, 4, 5];
434
435        // As Vec<u8> - encodes as array (each element individually)
436        let encoded_array = to_vec(&data).unwrap();
437
438        // As ByteBuf - encodes as byte string (raw bytes)
439        let byte_buf = ByteBuf::from(data.clone());
440        let encoded_bytes = to_vec(&byte_buf).unwrap();
441
442        // For small arrays, they might be similar, but ByteBuf uses raw bytes
443        // Array: 1 byte header + 5 bytes (one per element since values are < 24) = 6 bytes
444        // ByteBuf: 1 byte header + 5 bytes raw = 6 bytes
445        // For larger values or larger arrays, ByteBuf is more efficient
446
447        println!("Array encoding: {} bytes", encoded_array.len());
448        println!("Bytes encoding: {} bytes", encoded_bytes.len());
449
450        // ByteBuf: 1 byte header + 5 bytes data = 6 bytes
451        assert_eq!(encoded_bytes.len(), 6);
452        assert_eq!(encoded_bytes[0], (MAJOR_BYTES << 5) | 5);
453
454        // Array: 1 byte header + 5 bytes (small integers) = 6 bytes
455        assert_eq!(encoded_array.len(), 6);
456        assert_eq!(encoded_array[0], (MAJOR_ARRAY << 5) | 5);
457
458        let decoded: ByteBuf = from_slice(&encoded_bytes).unwrap();
459        assert_eq!(decoded.into_vec(), data);
460    }
461
462    #[test]
463    fn test_tagged_byte_array_overhead() {
464        use serde_bytes::ByteBuf;
465
466        // Test that tagged byte arrays (e.g., tag 64) have minimal overhead
467        let data: Vec<u8> = vec![1, 2, 3, 4, 5];
468        let byte_buf = ByteBuf::from(data.clone());
469
470        let mut buf = Vec::new();
471        let mut encoder = Encoder::new(&mut buf);
472        encoder.write_tag(TAG_UINT8_ARRAY).unwrap();
473        encoder.encode(&byte_buf).unwrap();
474
475        // Overhead: 2 bytes for tag (0xD8 0x40) + 1 byte for bytes type + 1 byte for length + 5 bytes data
476        assert_eq!(buf.len(), 8);
477
478        // Tag 64 encoded as 0xD8 0x40
479        assert_eq!(buf[0], 0xd8);
480        assert_eq!(buf[1], 64);
481        // Byte string with length 5
482        assert_eq!(buf[2], (MAJOR_BYTES << 5) | 5);
483        assert_eq!(&buf[3..], &[1, 2, 3, 4, 5]);
484    }
485
486    #[test]
487    fn test_performance_summary() {
488        use std::time::Instant;
489
490        use serde_bytes::ByteBuf;
491
492        // Demonstrate efficient encoding/decoding of binary data
493        println!("\n=== CBOR Binary Encoding Performance ===");
494
495        // Small array (5 bytes)
496        let small = ByteBuf::from(vec![1, 2, 3, 4, 5]);
497        let encoded_small = to_vec(&small).unwrap();
498        println!(
499            "5 bytes -> {} encoded bytes (overhead: {} bytes)",
500            encoded_small.len(),
501            encoded_small.len() - 5
502        );
503        assert_eq!(encoded_small.len(), 6); // 1 byte overhead
504
505        // 1KB array
506        let kb1_data: Vec<u8> = (0..1024).map(|i| (i % 256) as u8).collect();
507        let kb1 = ByteBuf::from(kb1_data);
508        let encoded_kb1 = to_vec(&kb1).unwrap();
509        println!(
510            "1 KB -> {} encoded bytes (overhead: {} bytes)",
511            encoded_kb1.len(),
512            encoded_kb1.len() - 1024
513        );
514        assert_eq!(encoded_kb1.len(), 1027); // 3 bytes overhead
515
516        // 100KB array
517        let kb100_data: Vec<u8> = (0..102400).map(|i| (i % 256) as u8).collect();
518        let kb100 = ByteBuf::from(kb100_data);
519        let encoded_kb100 = to_vec(&kb100).unwrap();
520        println!(
521            "100 KB -> {} encoded bytes (overhead: {} bytes)",
522            encoded_kb100.len(),
523            encoded_kb100.len() - 102400
524        );
525        assert_eq!(encoded_kb100.len(), 102405); // 5 bytes overhead
526
527        println!("\n--- Speed Tests ---");
528
529        // Speed test: 1MB encoding
530        let mb1_data: Vec<u8> = (0..1048576).map(|i| (i % 256) as u8).collect();
531        let mb1 = ByteBuf::from(mb1_data.clone());
532
533        let start = Instant::now();
534        let iterations = 100;
535        for _ in 0..iterations {
536            let _ = to_vec(&mb1).unwrap();
537        }
538        let encode_duration = start.elapsed();
539        let encode_throughput =
540            (1048576 * iterations) as f64 / encode_duration.as_secs_f64() / 1_048_576.0;
541        println!(
542            "Encode 1 MB x {}: {:?} ({:.1} MB/s)",
543            iterations, encode_duration, encode_throughput
544        );
545
546        // Speed test: 1MB decoding
547        let encoded_mb = to_vec(&mb1).unwrap();
548        let start = Instant::now();
549        for _ in 0..iterations {
550            let _: ByteBuf = from_slice(&encoded_mb).unwrap();
551        }
552        let decode_duration = start.elapsed();
553        let decode_throughput =
554            (1048576 * iterations) as f64 / decode_duration.as_secs_f64() / 1_048_576.0;
555        println!(
556            "Decode 1 MB x {}: {:?} ({:.1} MB/s)",
557            iterations, decode_duration, decode_throughput
558        );
559
560        println!("\nOverhead is minimal and speed is excellent!");
561        println!("Encoding is zero-copy - data is written directly.");
562        println!("Decoding allocates once - no per-element overhead.\n");
563    }
564
565    #[test]
566    fn test_encoding_speed_vs_size() {
567        use std::time::Instant;
568
569        use serde_bytes::ByteBuf;
570
571        println!("\n=== Encoding Speed vs Data Size ===");
572
573        let sizes = vec![1024, 10240, 102400, 1048576]; // 1KB, 10KB, 100KB, 1MB
574
575        for size in sizes {
576            let data: Vec<u8> = (0..size).map(|i| (i % 256) as u8).collect();
577            let byte_buf = ByteBuf::from(data);
578
579            let iterations = if size >= 1048576 { 10 } else { 100 };
580
581            let start = Instant::now();
582            for _ in 0..iterations {
583                let _ = to_vec(&byte_buf).unwrap();
584            }
585            let duration = start.elapsed();
586            let avg_ns = duration.as_nanos() / iterations as u128;
587            let throughput_mbps =
588                (size as f64 * iterations as f64) / duration.as_secs_f64() / 1_048_576.0;
589
590            println!(
591                "{:>7} bytes: {:>6} ns/op ({:>6.1} MB/s)",
592                size, avg_ns, throughput_mbps
593            );
594        }
595        println!();
596    }
597
598    #[test]
599    fn test_decoding_speed_vs_size() {
600        use std::time::Instant;
601
602        use serde_bytes::ByteBuf;
603
604        println!("\n=== Decoding Speed vs Data Size ===");
605
606        let sizes = vec![1024, 10240, 102400, 1048576]; // 1KB, 10KB, 100KB, 1MB
607
608        for size in sizes {
609            let data: Vec<u8> = (0..size).map(|i| (i % 256) as u8).collect();
610            let byte_buf = ByteBuf::from(data);
611            let encoded = to_vec(&byte_buf).unwrap();
612
613            let iterations = if size >= 1048576 { 10 } else { 100 };
614
615            let start = Instant::now();
616            for _ in 0..iterations {
617                let _: ByteBuf = from_slice(&encoded).unwrap();
618            }
619            let duration = start.elapsed();
620            let avg_ns = duration.as_nanos() / iterations as u128;
621            let throughput_mbps =
622                (size as f64 * iterations as f64) / duration.as_secs_f64() / 1_048_576.0;
623
624            println!(
625                "{:>7} bytes: {:>6} ns/op ({:>6.1} MB/s)",
626                size, avg_ns, throughput_mbps
627            );
628        }
629        println!();
630    }
631
632    #[test]
633    fn test_indefinite_array() {
634        // Manually encode an indefinite-length array
635        let mut buf = Vec::new();
636        let mut enc = Encoder::new(&mut buf);
637
638        // Start indefinite array
639        enc.write_array_indefinite().unwrap();
640        // Add elements
641        enc.encode(&1u32).unwrap();
642        enc.encode(&2u32).unwrap();
643        enc.encode(&3u32).unwrap();
644        // Write break
645        enc.write_break().unwrap();
646
647        // Verify encoding: 0x9F (array indefinite) + elements + 0xFF (break)
648        assert_eq!(buf[0], (MAJOR_ARRAY << 5) | INDEFINITE);
649        assert_eq!(buf[buf.len() - 1], BREAK);
650
651        // Decode should work
652        let decoded: Vec<u32> = from_slice(&buf).unwrap();
653        assert_eq!(decoded, vec![1, 2, 3]);
654    }
655
656    #[test]
657    fn test_indefinite_map() {
658        // Manually encode an indefinite-length map
659        let mut buf = Vec::new();
660        let mut enc = Encoder::new(&mut buf);
661
662        // Start indefinite map
663        enc.write_map_indefinite().unwrap();
664        // Add key-value pairs
665        enc.encode(&"a").unwrap();
666        enc.encode(&1u32).unwrap();
667        enc.encode(&"b").unwrap();
668        enc.encode(&2u32).unwrap();
669        // Write break
670        enc.write_break().unwrap();
671
672        // Verify encoding
673        assert_eq!(buf[0], (MAJOR_MAP << 5) | INDEFINITE);
674        assert_eq!(buf[buf.len() - 1], BREAK);
675
676        // Decode should work
677        let decoded: HashMap<String, u32> = from_slice(&buf).unwrap();
678        assert_eq!(decoded.get("a"), Some(&1));
679        assert_eq!(decoded.get("b"), Some(&2));
680    }
681
682    #[test]
683    fn test_indefinite_byte_string() {
684        use serde_bytes::ByteBuf;
685
686        // Manually encode indefinite-length byte string (chunked)
687        let mut buf = Vec::new();
688        buf.push((MAJOR_BYTES << 5) | INDEFINITE); // Start indefinite bytes
689
690        // Add chunks as byte strings
691        let chunk1 = vec![1u8, 2, 3];
692        let chunk1_enc = to_vec(&ByteBuf::from(chunk1.clone())).unwrap();
693        buf.extend_from_slice(&chunk1_enc);
694
695        let chunk2 = vec![4u8, 5];
696        let chunk2_enc = to_vec(&ByteBuf::from(chunk2.clone())).unwrap();
697        buf.extend_from_slice(&chunk2_enc);
698
699        buf.push(BREAK); // End indefinite
700
701        // Decode should concatenate chunks
702        let decoded: ByteBuf = from_slice(&buf).unwrap();
703        assert_eq!(decoded.into_vec(), vec![1, 2, 3, 4, 5]);
704    }
705
706    #[test]
707    fn test_indefinite_text_string() {
708        // Manually encode indefinite-length text string (chunked)
709        let mut buf = Vec::new();
710        buf.push((MAJOR_TEXT << 5) | INDEFINITE); // Start indefinite text
711
712        // Add chunks
713        let chunk1 = "Hello";
714        let chunk1_enc = to_vec(&chunk1).unwrap();
715        buf.extend_from_slice(&chunk1_enc);
716
717        let chunk2 = " World";
718        let chunk2_enc = to_vec(&chunk2).unwrap();
719        buf.extend_from_slice(&chunk2_enc);
720
721        buf.push(BREAK); // End indefinite
722
723        // Decode should concatenate chunks
724        let decoded: String = from_slice(&buf).unwrap();
725        assert_eq!(decoded, "Hello World");
726    }
727
728    #[test]
729    fn test_ser_module_serializer() {
730        use crate::ser::Serializer;
731
732        // Test that ser::Serializer works correctly
733        let buf = Vec::new();
734        let mut serializer = Serializer::new(buf);
735
736        let data = vec![1, 2, 3];
737        data.serialize(&mut serializer).unwrap();
738
739        let encoded = serializer.into_inner();
740        let decoded: Vec<i32> = from_slice(&encoded).unwrap();
741        assert_eq!(decoded, vec![1, 2, 3]);
742    }
743
744    #[test]
745    fn test_struct_with_option_fields() {
746        use std::collections::HashMap;
747
748        #[derive(Debug, Serialize, Deserialize, PartialEq)]
749        struct TestData {
750            name: String,
751            value: u32,
752            optional_map: Option<HashMap<String, String>>,
753            optional_string: Option<String>,
754        }
755
756        // Test with Some values
757        let mut map = HashMap::new();
758        map.insert("key1".to_string(), "value1".to_string());
759
760        let data_with_some = TestData {
761            name: "test".to_string(),
762            value: 42,
763            optional_map: Some(map),
764            optional_string: Some("hello".to_string()),
765        };
766
767        let encoded = to_vec(&data_with_some).unwrap();
768        let decoded: TestData = from_slice(&encoded).unwrap();
769        assert_eq!(data_with_some, decoded);
770
771        // Test with None values
772        let data_with_none = TestData {
773            name: "test".to_string(),
774            value: 42,
775            optional_map: None,
776            optional_string: None,
777        };
778
779        let encoded_none = to_vec(&data_with_none).unwrap();
780        let decoded_none: TestData = from_slice(&encoded_none).unwrap();
781        assert_eq!(data_with_none, decoded_none);
782    }
783
784    #[test]
785    fn test_nested_option_maps() {
786        #[derive(Debug, Serialize, Deserialize, PartialEq)]
787        struct Outer {
788            data: Option<Inner>,
789        }
790
791        #[derive(Debug, Serialize, Deserialize, PartialEq)]
792        struct Inner {
793            values: HashMap<String, i32>,
794        }
795
796        let mut values = HashMap::new();
797        values.insert("a".to_string(), 1);
798        values.insert("b".to_string(), 2);
799
800        let outer = Outer {
801            data: Some(Inner { values }),
802        };
803
804        let encoded = to_vec(&outer).unwrap();
805        println!("Encoded bytes: {:?}", encoded);
806        let decoded: Outer = from_slice(&encoded).unwrap();
807        assert_eq!(outer, decoded);
808    }
809
810    #[test]
811    fn test_option_field_counting() {
812        // Test to understand how serde counts fields with Option
813        #[derive(Debug, Serialize)]
814        struct WithOptions {
815            field1: String,
816            field2: Option<String>,
817            field3: Option<String>,
818        }
819
820        let data = WithOptions {
821            field1: "hello".to_string(),
822            field2: Some("world".to_string()),
823            field3: None,
824        };
825
826        // This should trigger the error if serialize_struct gets wrong len
827        let encoded = to_vec(&data).unwrap();
828        println!("Encoded bytes: {:?}", encoded);
829
830        // Check the first byte - should be a map with the right number of entries
831        // Map header format: major type 5 (0xA0 | count) or 0xB8 + count byte
832        println!("First byte: 0x{:02x}", encoded[0]);
833    }
834
835    #[test]
836    fn test_trait_object_serialization() {
837        // Reproduce the AssertionCbor scenario
838        use std::collections::HashMap;
839
840        #[derive(Debug, Serialize, Deserialize, PartialEq)]
841        struct TestStruct {
842            name: String,
843            values: HashMap<String, String>,
844        }
845
846        let mut map = HashMap::new();
847        map.insert("key1".to_string(), "value1".to_string());
848        map.insert("key2".to_string(), "value2".to_string());
849
850        let obj = TestStruct {
851            name: "test".to_string(),
852            values: map,
853        };
854
855        // Serialize directly
856        let encoded = to_vec(&obj).unwrap();
857        println!("Encoded: {:?}", encoded);
858
859        // Decode should work
860        let decoded: TestStruct = from_slice(&encoded).unwrap();
861        assert_eq!(obj, decoded);
862    }
863
864    #[test]
865    fn test_skip_serializing_if() {
866        // This reproduces the Actions struct issue
867        #[derive(Debug, Serialize, Deserialize, PartialEq)]
868        struct SkipTest {
869            always: String,
870            #[serde(skip_serializing_if = "Option::is_none")]
871            sometimes: Option<String>,
872            #[serde(skip_serializing_if = "Option::is_none")]
873            rarely: Option<Vec<String>>,
874        }
875
876        // Test with None values - this will try to serialize 3 fields but skip 2
877        let obj = SkipTest {
878            always: "hello".to_string(),
879            sometimes: None,
880            rarely: None,
881        };
882
883        // This should work - serde should tell us len=1, not len=3
884        let encoded = to_vec(&obj).unwrap();
885        println!("Encoded skip test: {:?}", encoded);
886        println!("First byte: 0x{:02x}", encoded[0]);
887
888        let decoded: SkipTest = from_slice(&encoded).unwrap();
889        assert_eq!(obj, decoded);
890    }
891
892    #[test]
893    fn test_actions_like_struct() {
894        // Reproduce the exact Actions structure
895        use std::collections::HashMap;
896
897        #[derive(Debug, Serialize, Deserialize, PartialEq)]
898        struct ActionLike {
899            params: Option<HashMap<String, Vec<u8>>>,
900        }
901
902        #[derive(Debug, Serialize, Deserialize, PartialEq)]
903        struct ActionsLike {
904            actions: Vec<ActionLike>,
905            #[serde(skip_serializing_if = "Option::is_none")]
906            metadata: Option<HashMap<String, String>>,
907        }
908
909        let mut params = HashMap::new();
910        params.insert("key1".to_string(), vec![1, 2, 3]);
911
912        let mut metadata = HashMap::new();
913        metadata.insert("meta1".to_string(), "value1".to_string());
914
915        let obj = ActionsLike {
916            actions: vec![ActionLike {
917                params: Some(params),
918            }],
919            metadata: Some(metadata),
920        };
921
922        // This might trigger the error if there's an issue with HashMap serialization
923        let encoded = to_vec(&obj).unwrap();
924        println!("Encoded actions-like: {} bytes", encoded.len());
925
926        let decoded: ActionsLike = from_slice(&encoded).unwrap();
927        assert_eq!(obj, decoded);
928    }
929
930    #[test]
931    fn test_flatten_attribute() {
932        // Test #[serde(flatten)] which causes indefinite-length serialization
933        use std::collections::HashMap;
934
935        #[derive(Debug, Serialize, Deserialize, PartialEq)]
936        struct WithFlatten {
937            regular_field: String,
938            #[serde(flatten)]
939            flattened: HashMap<String, String>,
940        }
941
942        let mut map = HashMap::new();
943        map.insert("extra1".to_string(), "value1".to_string());
944        map.insert("extra2".to_string(), "value2".to_string());
945
946        let obj = WithFlatten {
947            regular_field: "test".to_string(),
948            flattened: map,
949        };
950
951        // This WILL trigger the indefinite-length path due to flatten
952        // Our fallback to Value should handle it
953        let encoded = to_vec(&obj).unwrap();
954        println!("Encoded flattened: {} bytes", encoded.len());
955        println!("First byte: 0x{:02x}", encoded[0]);
956
957        let decoded: WithFlatten = from_slice(&encoded).unwrap();
958        assert_eq!(obj, decoded);
959    }
960
961    #[test]
962    fn test_enum_serialization() {
963        // Test different enum representation styles
964
965        // Unit variant (serializes as string)
966        #[derive(Debug, Serialize, Deserialize, PartialEq)]
967        enum SimpleEnum {
968            Temporal,
969            Spatial,
970            Other,
971        }
972
973        let val = SimpleEnum::Temporal;
974        let encoded = to_vec(&val).unwrap();
975        println!("Simple enum encoded: {:?}", encoded);
976        let decoded: SimpleEnum = from_slice(&encoded).unwrap();
977        assert_eq!(val, decoded);
978
979        // With rename
980        #[derive(Debug, Serialize, Deserialize, PartialEq)]
981        #[serde(rename_all = "lowercase")]
982        enum RenamedEnum {
983            Temporal,
984            Spatial,
985        }
986
987        let val2 = RenamedEnum::Temporal;
988        let encoded2 = to_vec(&val2).unwrap();
989        println!("Renamed enum encoded: {:?}", encoded2);
990        let decoded2: RenamedEnum = from_slice(&encoded2).unwrap();
991        assert_eq!(val2, decoded2);
992
993        // Enum with data
994        #[derive(Debug, Serialize, Deserialize, PartialEq)]
995        enum DataEnum {
996            Unit,
997            Newtype(String),
998            Tuple(i32, String),
999            Struct { field: String },
1000        }
1001
1002        let val3 = DataEnum::Struct {
1003            field: "test".to_string(),
1004        };
1005        let encoded3 = to_vec(&val3).unwrap();
1006        println!("Struct variant encoded: {:?}", encoded3);
1007        let decoded3: DataEnum = from_slice(&encoded3).unwrap();
1008        assert_eq!(val3, decoded3);
1009    }
1010
1011    #[test]
1012    fn test_float_serialization() {
1013        // Test f32
1014        let f32_val = 4.0f32;
1015        let encoded = to_vec(&f32_val).unwrap();
1016        println!("f32 encoded: {:?}", encoded);
1017        // Should be: major type 7 (0xE0), additional info 26 (0x1A), then 4 bytes
1018        assert_eq!(encoded[0], (MAJOR_SIMPLE << 5) | 26);
1019        let decoded: f32 = from_slice(&encoded).unwrap();
1020        assert_eq!(f32_val, decoded);
1021
1022        // Test f64 - behavior depends on compact_floats feature
1023        let f64_val = 1.0e+300f64;
1024        let encoded = to_vec(&f64_val).unwrap();
1025        println!("f64 encoded: {:?}", encoded);
1026        // Should be: major type 7 (0xE0), additional info 27 (0x1B), then 8 bytes
1027        assert_eq!(encoded[0], (MAJOR_SIMPLE << 5) | 27);
1028        let decoded: f64 = from_slice(&encoded).unwrap();
1029        assert_eq!(f64_val, decoded);
1030
1031        #[cfg(feature = "compact_floats")]
1032        {
1033            // With compact_floats enabled, simple values optimize to f16
1034            let simple_val = 2.5f64;
1035            let encoded_simple = to_vec(&simple_val).unwrap();
1036            // Should optimize to f16 (FLOAT16 = 25)
1037            assert_eq!(encoded_simple[0], (MAJOR_SIMPLE << 5) | 25);
1038            let decoded_simple: f64 = from_slice(&encoded_simple).unwrap();
1039            assert_eq!(simple_val, decoded_simple);
1040        }
1041
1042        #[cfg(not(feature = "compact_floats"))]
1043        {
1044            // Without compact_floats, all f64 values use full precision
1045            let simple_val = 2.5f64;
1046            let encoded_simple = to_vec(&simple_val).unwrap();
1047            // Should use f64 (FLOAT64 = 27)
1048            assert_eq!(encoded_simple[0], (MAJOR_SIMPLE << 5) | 27);
1049            let decoded_simple: f64 = from_slice(&encoded_simple).unwrap();
1050            assert_eq!(simple_val, decoded_simple);
1051        }
1052
1053        // Test in a struct
1054        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1055        struct ExifData {
1056            f_number: f64,
1057            exposure_time: f32,
1058            zoom_ratio: f64,
1059        }
1060
1061        let exif = ExifData {
1062            f_number: 4.0,
1063            exposure_time: 0.01,
1064            zoom_ratio: 2.0,
1065        };
1066
1067        let encoded = to_vec(&exif).unwrap();
1068        println!("Exif data encoded: {} bytes", encoded.len());
1069        let decoded: ExifData = from_slice(&encoded).unwrap();
1070        assert_eq!(exif, decoded);
1071    }
1072
1073    #[test]
1074    fn test_invalid_cbor_trailing_bytes() {
1075        use crate::Value;
1076
1077        // These bytes are just a sequence of small integers with no structure
1078        // The first byte (0x0d = 13) is a valid CBOR integer, but the rest are trailing garbage
1079        let invalid_bytes = vec![0x0d, 0x0e, 0x0a, 0x0d, 0x0b, 0x0e, 0x0e, 0x0f];
1080
1081        let result: Result<Value> = from_slice(&invalid_bytes);
1082        assert!(result.is_err(), "Should fail on trailing bytes");
1083
1084        if let Err(e) = result {
1085            let msg = format!("{:?}", e);
1086            assert!(
1087                msg.contains("trailing"),
1088                "Error should mention trailing data: {}",
1089                msg
1090            );
1091        }
1092    }
1093
1094    #[test]
1095    fn test_empty_input() {
1096        use crate::Value;
1097
1098        let empty_bytes = vec![];
1099        let result: Result<Value> = from_slice(&empty_bytes);
1100        assert!(result.is_err(), "Should fail on empty input");
1101
1102        if let Err(e) = result {
1103            let msg = format!("{:?}", e);
1104            assert!(
1105                msg.contains("empty"),
1106                "Error should mention empty input: {}",
1107                msg
1108            );
1109        }
1110    }
1111
1112    #[test]
1113    fn test_incomplete_cbor() {
1114        // Start of an array but incomplete
1115        let incomplete = vec![0x85]; // array of 5 elements, but no elements follow
1116
1117        let result: Result<Vec<u32>> = from_slice(&incomplete);
1118        assert!(result.is_err(), "Should fail on incomplete CBOR");
1119    }
1120
1121    #[test]
1122    fn test_valid_cbor_all_bytes_consumed() {
1123        // Valid integer should consume exactly 1 byte
1124        let valid = vec![0x0d]; // integer 13
1125        let result: Result<u32> = from_slice(&valid);
1126        assert!(result.is_ok(), "Should succeed on valid CBOR");
1127        assert_eq!(result.unwrap(), 13);
1128    }
1129
1130    #[test]
1131    fn test_with_max_allocation_rejects_oversized() {
1132        use std::io::Cursor;
1133
1134        use crate::{Value, decoder::Decoder};
1135
1136        // Create CBOR claiming 100MB text string
1137        // 0x7b = major type 3 (text), additional info 27 (8-byte length)
1138        let mut cbor = vec![0x7b];
1139        let length: u64 = 100 * 1024 * 1024; // 100MB
1140        cbor.extend_from_slice(&length.to_be_bytes());
1141        cbor.extend_from_slice(b"attack"); // Add some data (not 100MB)
1142
1143        // Set limit to 10MB - should reject before attempting allocation
1144        let cursor = Cursor::new(&cbor[..]);
1145        let mut decoder = Decoder::new(cursor).with_max_allocation(10 * 1024 * 1024);
1146        let result: Result<Value> = decoder.decode();
1147
1148        assert!(
1149            result.is_err(),
1150            "Should reject allocation exceeding max_allocation"
1151        );
1152
1153        // Verify error message mentions the limit
1154        if let Err(e) = result {
1155            let msg = format!("{:?}", e);
1156            assert!(
1157                msg.contains("exceeds maximum") || msg.contains("Allocation size"),
1158                "Error should mention allocation limit: {}",
1159                msg
1160            );
1161        }
1162    }
1163
1164    #[test]
1165    fn test_with_max_allocation_accepts_within_limit() {
1166        use std::io::Cursor;
1167
1168        use crate::{Value, decoder::Decoder};
1169
1170        // Create a valid 1KB text string
1171        // 0x79 = major type 3 (text), additional info 25 (2-byte length)
1172        let mut cbor = vec![0x79];
1173        let length: u16 = 1024;
1174        cbor.extend_from_slice(&length.to_be_bytes());
1175        cbor.resize(3 + 1024, b'A'); // Add 1KB of actual data
1176
1177        // Set limit to 10MB - should accept
1178        let cursor = Cursor::new(&cbor[..]);
1179        let mut decoder = Decoder::new(cursor).with_max_allocation(10 * 1024 * 1024);
1180        let result: Result<Value> = decoder.decode();
1181
1182        assert!(
1183            result.is_ok(),
1184            "Should accept allocation within max_allocation"
1185        );
1186
1187        // Verify we got the expected string
1188        if let Ok(Value::Text(s)) = result {
1189            assert_eq!(s.len(), 1024, "Should decode 1KB string");
1190            assert!(s.chars().all(|c| c == 'A'), "String should be all 'A's");
1191        } else {
1192            panic!("Expected Text value, got: {:?}", result);
1193        }
1194    }
1195
1196    #[test]
1197    fn test_with_max_allocation_byte_string() {
1198        use std::io::Cursor;
1199
1200        use crate::{Value, decoder::Decoder};
1201
1202        // Test with byte string (major type 2) instead of text string
1203        // 0x5a = major type 2 (bytes), additional info 26 (4-byte length)
1204        let mut cbor = vec![0x5a];
1205        let length: u32 = 50 * 1024 * 1024; // 50MB
1206        cbor.extend_from_slice(&length.to_be_bytes());
1207        cbor.extend_from_slice(&[0xff, 0xfe]); // Add some data
1208
1209        // Set limit to 10MB - should reject
1210        let cursor = Cursor::new(&cbor[..]);
1211        let mut decoder = Decoder::new(cursor).with_max_allocation(10 * 1024 * 1024);
1212        let result: Result<Value> = decoder.decode();
1213
1214        assert!(result.is_err(), "Should reject byte string exceeding limit");
1215
1216        if let Err(e) = result {
1217            let msg = format!("{:?}", e);
1218            assert!(
1219                msg.contains("exceeds maximum") || msg.contains("Allocation size"),
1220                "Error should mention allocation limit for byte string: {}",
1221                msg
1222            );
1223        }
1224    }
1225
1226    #[test]
1227    fn test_default_from_slice_has_protection() {
1228        // Test that the default from_slice has built-in OOM protection
1229        // Create CBOR claiming 200MB text string (exceeds default 100MB limit)
1230        let mut cbor = vec![0x7b]; // major type 3 (text), 8-byte length
1231        let length: u64 = 200 * 1024 * 1024; // 200MB
1232        cbor.extend_from_slice(&length.to_be_bytes());
1233        cbor.extend_from_slice(b"malicious"); // Add some data
1234
1235        // This should be automatically rejected by the default 100MB limit
1236        let result: Result<Value> = from_slice(&cbor);
1237
1238        assert!(
1239            result.is_err(),
1240            "from_slice should have default protection against oversized allocations"
1241        );
1242
1243        if let Err(e) = result {
1244            let msg = format!("{:?}", e);
1245            assert!(
1246                msg.contains("exceeds maximum") || msg.contains("Allocation size"),
1247                "Error should mention allocation limit: {}",
1248                msg
1249            );
1250        }
1251    }
1252
1253    #[test]
1254    #[allow(clippy::same_item_push)]
1255    fn test_deep_nesting_protection() {
1256        // Test protection against deeply nested structures that cause stack overflow
1257        // Create CBOR with 200 nested arrays (exceeds default depth limit of 128)
1258        let mut cbor = Vec::new();
1259
1260        // Start with 200 nested indefinite-length arrays
1261        for _ in 0..200 {
1262            cbor.push(0x9f); // indefinite-length array
1263        }
1264
1265        cbor.push(0x01); // a simple integer value at the center
1266
1267        // Close all 200 arrays
1268        for _ in 0..200 {
1269            cbor.push(0xff); // break/end marker
1270        }
1271
1272        // This should be rejected due to excessive nesting depth
1273        let result: Result<Value> = from_slice(&cbor);
1274
1275        assert!(
1276            result.is_err(),
1277            "from_slice should reject deeply nested structures"
1278        );
1279
1280        if let Err(e) = result {
1281            let msg = format!("{:?}", e);
1282            assert!(
1283                msg.contains("nesting depth") || msg.contains("exceeds maximum"),
1284                "Error should mention nesting depth: {}",
1285                msg
1286            );
1287        }
1288    }
1289
1290    // ========== Additional Decoder Tests ==========
1291
1292    #[test]
1293    fn test_decoder_all_length_variants() {
1294        // Test all length encoding sizes: 0-23, 24, 25, 26, 27
1295        // Small (0-23): direct
1296        let cbor = vec![0x17]; // 23
1297        let val: u64 = from_slice(&cbor).unwrap();
1298        assert_eq!(val, 23);
1299
1300        // 1-byte (24)
1301        let cbor = vec![0x18, 100]; // 100
1302        let val: u64 = from_slice(&cbor).unwrap();
1303        assert_eq!(val, 100);
1304
1305        // 2-byte (25)
1306        let cbor = vec![0x19, 0x01, 0x00]; // 256
1307        let val: u64 = from_slice(&cbor).unwrap();
1308        assert_eq!(val, 256);
1309
1310        // 4-byte (26)
1311        let cbor = vec![0x1a, 0x00, 0x01, 0x00, 0x00]; // 65536
1312        let val: u64 = from_slice(&cbor).unwrap();
1313        assert_eq!(val, 65536);
1314
1315        // 8-byte (27)
1316        let cbor = vec![0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]; // 4294967296
1317        let val: u64 = from_slice(&cbor).unwrap();
1318        assert_eq!(val, 4294967296);
1319    }
1320
1321    #[test]
1322    fn test_decoder_negative_integer_lengths() {
1323        // Test negative number with different length encodings
1324        let cbor = vec![0x20]; // -1
1325        let val: i64 = from_slice(&cbor).unwrap();
1326        assert_eq!(val, -1);
1327
1328        let cbor = vec![0x38, 0xff]; // -256
1329        let val: i64 = from_slice(&cbor).unwrap();
1330        assert_eq!(val, -256);
1331
1332        let cbor = vec![0x39, 0x01, 0x00]; // -257
1333        let val: i64 = from_slice(&cbor).unwrap();
1334        assert_eq!(val, -257);
1335    }
1336
1337    #[test]
1338    fn test_decoder_invalid_utf8() {
1339        // Invalid UTF-8 in text string
1340        let mut cbor = vec![0x64]; // text string, length 4
1341        cbor.extend_from_slice(&[0xff, 0xfe, 0xfd, 0xfc]); // invalid UTF-8
1342        let result: Result<String> = from_slice(&cbor);
1343        assert!(matches!(result, Err(Error::InvalidUtf8)));
1344    }
1345
1346    #[test]
1347    fn test_decoder_indefinite_text_wrong_chunk_type() {
1348        // Indefinite text string with byte string chunk (invalid)
1349        let mut cbor = vec![0x7f]; // indefinite text string start
1350        cbor.push(0x42); // byte string chunk instead of text (wrong!)
1351        cbor.extend_from_slice(&[0x01, 0x02]);
1352        cbor.push(0xff); // break
1353
1354        let result: Result<String> = from_slice(&cbor);
1355        assert!(result.is_err());
1356        assert!(
1357            result
1358                .unwrap_err()
1359                .to_string()
1360                .contains("text string chunks must be text strings")
1361        );
1362    }
1363
1364    #[test]
1365    fn test_decoder_indefinite_bytes_wrong_chunk_type() {
1366        // Indefinite byte string with text string chunk (invalid)
1367        let mut cbor = vec![0x5f]; // indefinite byte string start
1368        cbor.push(0x62); // text string chunk instead of bytes (wrong!)
1369        cbor.extend_from_slice(&[0x68, 0x69]); // "hi"
1370        cbor.push(0xff); // break
1371
1372        let result: Result<Vec<u8>> = from_slice(&cbor);
1373        assert!(result.is_err());
1374        assert!(
1375            result
1376                .unwrap_err()
1377                .to_string()
1378                .contains("byte string chunks must be byte strings")
1379        );
1380    }
1381
1382    #[test]
1383    fn test_decoder_allocation_limit_exceeded() {
1384        // Try to allocate more than the limit
1385        let result: Result<Vec<u8>> =
1386            crate::decoder::from_slice_with_limit(&[0x5a, 0xff, 0xff, 0xff, 0xff], 1000);
1387        assert!(result.is_err());
1388        assert!(result.unwrap_err().to_string().contains("exceeds maximum"));
1389    }
1390
1391    #[test]
1392    fn test_decoder_from_reader() {
1393        let data = to_vec(&42i32).unwrap();
1394        let cursor = std::io::Cursor::new(data);
1395        let val: i32 = from_reader(cursor).unwrap();
1396        assert_eq!(val, 42);
1397    }
1398
1399    #[test]
1400    fn test_decoder_from_reader_with_limit() {
1401        let data = to_vec(&"hello").unwrap();
1402        let cursor = std::io::Cursor::new(data);
1403        let val: String = crate::decoder::from_reader_with_limit(cursor, 1000).unwrap();
1404        assert_eq!(val, "hello");
1405    }
1406
1407    #[test]
1408    fn test_decoder_trailing_bytes_error() {
1409        // Valid CBOR followed by extra bytes
1410        let mut cbor = to_vec(&42i32).unwrap();
1411        cbor.extend_from_slice(&[0x01, 0x02, 0x03]); // extra bytes
1412
1413        let result: Result<i32> = from_slice(&cbor);
1414        assert!(result.is_err());
1415        assert!(
1416            result
1417                .unwrap_err()
1418                .to_string()
1419                .contains("unexpected trailing data")
1420        );
1421    }
1422
1423    #[test]
1424    fn test_decoder_invalid_simple_value() {
1425        // Simple value with reserved info
1426        let cbor = vec![0xf8]; // reserved simple value
1427        let result: Result<i32> = from_slice(&cbor);
1428        assert!(result.is_err());
1429    }
1430
1431    #[test]
1432    fn test_decoder_tag_indefinite_error() {
1433        // Tag with indefinite length (invalid)
1434        let cbor = vec![0xdf]; // tag with indefinite length marker
1435        let result: Result<i32> = from_slice(&cbor);
1436        assert!(result.is_err());
1437    }
1438
1439    // ========== Additional Encoder Tests ==========
1440
1441    #[test]
1442    fn test_encoder_all_integer_sizes() {
1443        // i8
1444        let val: i8 = -127;
1445        let cbor = to_vec(&val).unwrap();
1446        let decoded: i8 = from_slice(&cbor).unwrap();
1447        assert_eq!(val, decoded);
1448
1449        // i16
1450        let val: i16 = -30000;
1451        let cbor = to_vec(&val).unwrap();
1452        let decoded: i16 = from_slice(&cbor).unwrap();
1453        assert_eq!(val, decoded);
1454
1455        // i32
1456        let val: i32 = -2000000;
1457        let cbor = to_vec(&val).unwrap();
1458        let decoded: i32 = from_slice(&cbor).unwrap();
1459        assert_eq!(val, decoded);
1460
1461        // u8
1462        let val: u8 = 255;
1463        let cbor = to_vec(&val).unwrap();
1464        let decoded: u8 = from_slice(&cbor).unwrap();
1465        assert_eq!(val, decoded);
1466
1467        // u16
1468        let val: u16 = 65000;
1469        let cbor = to_vec(&val).unwrap();
1470        let decoded: u16 = from_slice(&cbor).unwrap();
1471        assert_eq!(val, decoded);
1472
1473        // u32
1474        let val: u32 = 4000000;
1475        let cbor = to_vec(&val).unwrap();
1476        let decoded: u32 = from_slice(&cbor).unwrap();
1477        assert_eq!(val, decoded);
1478    }
1479
1480    #[test]
1481    fn test_encoder_indefinite_array() {
1482        use crate::Encoder;
1483        let mut buf = Vec::new();
1484        let mut enc = Encoder::new(&mut buf);
1485
1486        // Test indefinite array
1487        enc.write_array_indefinite().unwrap();
1488        enc.encode(&1).unwrap();
1489        enc.encode(&2).unwrap();
1490        enc.encode(&3).unwrap();
1491        enc.write_break().unwrap();
1492
1493        // Should decode as [1, 2, 3]
1494        let decoded: Vec<i32> = from_slice(&buf).unwrap();
1495        assert_eq!(decoded, vec![1, 2, 3]);
1496    }
1497
1498    #[test]
1499    fn test_encoder_indefinite_map() {
1500        use crate::Encoder;
1501        let mut buf = Vec::new();
1502        let mut enc = Encoder::new(&mut buf);
1503
1504        // Test indefinite map
1505        enc.write_map_indefinite().unwrap();
1506        enc.encode(&"key1").unwrap();
1507        enc.encode(&100).unwrap();
1508        enc.encode(&"key2").unwrap();
1509        enc.encode(&200).unwrap();
1510        enc.write_break().unwrap();
1511
1512        // Should decode as map
1513        let decoded: std::collections::HashMap<String, i32> = from_slice(&buf).unwrap();
1514        assert_eq!(decoded.get("key1"), Some(&100));
1515        assert_eq!(decoded.get("key2"), Some(&200));
1516    }
1517
1518    #[test]
1519    fn test_encoder_struct_variant() {
1520        #[derive(Serialize, Deserialize, PartialEq, Debug)]
1521        enum TestEnum {
1522            StructVariant { x: i32, y: String },
1523        }
1524
1525        let val = TestEnum::StructVariant {
1526            x: 42,
1527            y: "test".to_string(),
1528        };
1529        let cbor = to_vec(&val).unwrap();
1530        let decoded: TestEnum = from_slice(&cbor).unwrap();
1531        assert_eq!(val, decoded);
1532    }
1533
1534    #[test]
1535    fn test_encoder_tuple_variant() {
1536        #[derive(Serialize, Deserialize, PartialEq, Debug)]
1537        enum TestEnum {
1538            TupleVariant(i32, String),
1539        }
1540
1541        let val = TestEnum::TupleVariant(42, "test".to_string());
1542        let cbor = to_vec(&val).unwrap();
1543        let decoded: TestEnum = from_slice(&cbor).unwrap();
1544        assert_eq!(val, decoded);
1545    }
1546
1547    #[test]
1548    fn test_encoder_char() {
1549        let val = 'A';
1550        let cbor = to_vec(&val).unwrap();
1551        let decoded: char = from_slice(&cbor).unwrap();
1552        assert_eq!(val, decoded);
1553
1554        let val = '界'; // multi-byte character
1555        let cbor = to_vec(&val).unwrap();
1556        let decoded: char = from_slice(&cbor).unwrap();
1557        assert_eq!(val, decoded);
1558    }
1559
1560    #[test]
1561    fn test_encoder_unit_variant() {
1562        #[derive(Serialize, Deserialize, PartialEq, Debug)]
1563        enum TestEnum {
1564            UnitVariant,
1565        }
1566
1567        let val = TestEnum::UnitVariant;
1568        let cbor = to_vec(&val).unwrap();
1569        let decoded: TestEnum = from_slice(&cbor).unwrap();
1570        assert_eq!(val, decoded);
1571    }
1572
1573    #[test]
1574    fn test_encoder_newtype_variant() {
1575        #[derive(Serialize, Deserialize, PartialEq, Debug)]
1576        enum TestEnum {
1577            NewtypeVariant(String),
1578        }
1579
1580        let val = TestEnum::NewtypeVariant("test".to_string());
1581        let cbor = to_vec(&val).unwrap();
1582        let decoded: TestEnum = from_slice(&cbor).unwrap();
1583        assert_eq!(val, decoded);
1584    }
1585
1586    #[test]
1587    fn test_encoder_tuple_struct() {
1588        #[derive(Serialize, Deserialize, PartialEq, Debug)]
1589        struct TupleStruct(i32, String, bool);
1590
1591        let val = TupleStruct(42, "test".to_string(), true);
1592        let cbor = to_vec(&val).unwrap();
1593        let decoded: TupleStruct = from_slice(&cbor).unwrap();
1594        assert_eq!(val, decoded);
1595    }
1596
1597    #[test]
1598    fn test_encoder_into_inner() {
1599        use crate::Encoder;
1600        let buf = Vec::new();
1601        let mut enc = Encoder::new(buf);
1602        enc.encode(&42).unwrap();
1603        let result = enc.into_inner();
1604        assert!(!result.is_empty());
1605    }
1606
1607    #[test]
1608    fn test_encoder_f32_precision() {
1609        let val: f32 = 3.15;
1610        let cbor = to_vec(&val).unwrap();
1611        let decoded: f32 = from_slice(&cbor).unwrap();
1612        assert!((val - decoded).abs() < 0.00001);
1613    }
1614
1615    #[test]
1616    fn test_encoder_to_writer() {
1617        let mut buf = Vec::new();
1618        to_writer(&mut buf, &42i32).unwrap();
1619        let decoded: i32 = from_slice(&buf).unwrap();
1620        assert_eq!(decoded, 42);
1621    }
1622
1623    // ============================================================================
1624    // Comprehensive Deserialization Coverage Tests
1625    // ============================================================================
1626
1627    #[test]
1628    fn test_decode_various_integer_sizes() {
1629        // Small integers (0-23) - single byte
1630        let small: u8 = 10;
1631        let encoded = to_vec(&small).unwrap();
1632        assert_eq!(encoded.len(), 1);
1633        assert_eq!(from_slice::<u8>(&encoded).unwrap(), 10);
1634
1635        // u8 size (24-255) - 2 bytes
1636        let medium: u8 = 200;
1637        let encoded = to_vec(&medium).unwrap();
1638        assert_eq!(from_slice::<u8>(&encoded).unwrap(), 200);
1639
1640        // u16 size - 3 bytes
1641        let large: u16 = 1000;
1642        let encoded = to_vec(&large).unwrap();
1643        assert_eq!(from_slice::<u16>(&encoded).unwrap(), 1000);
1644
1645        // u32 size - 5 bytes
1646        let huge: u32 = 100_000;
1647        let encoded = to_vec(&huge).unwrap();
1648        assert_eq!(from_slice::<u32>(&encoded).unwrap(), 100_000);
1649
1650        // u64 size - 9 bytes
1651        let enormous: u64 = 10_000_000_000;
1652        let encoded = to_vec(&enormous).unwrap();
1653        assert_eq!(from_slice::<u64>(&encoded).unwrap(), 10_000_000_000);
1654
1655        // Negative integers
1656        let neg_small: i8 = -10;
1657        let encoded = to_vec(&neg_small).unwrap();
1658        assert_eq!(from_slice::<i8>(&encoded).unwrap(), -10);
1659
1660        let neg_large: i64 = -1_000_000;
1661        let encoded = to_vec(&neg_large).unwrap();
1662        assert_eq!(from_slice::<i64>(&encoded).unwrap(), -1_000_000);
1663    }
1664
1665    #[test]
1666    fn test_decode_recursion_depth_limit() {
1667        use std::io::Cursor;
1668
1669        use crate::decoder::Decoder;
1670
1671        // Create a deeply nested array structure that exceeds the default limit
1672        let mut cbor = vec![0x9f]; // Start indefinite array
1673        // Nest 150 levels deep (exceeds DEFAULT_MAX_DEPTH of 128)
1674        cbor.extend(std::iter::repeat_n(0x9f, 150));
1675        // Add a simple value at the end
1676        cbor.push(0x00); // integer 0
1677        // Close all arrays
1678        cbor.extend(std::iter::repeat_n(0xff, 151));
1679
1680        let mut decoder = Decoder::new(Cursor::new(&cbor[..]));
1681        let result: Result<Value> = decoder.decode();
1682        assert!(result.is_err());
1683        let err_msg = result.unwrap_err().to_string();
1684        assert!(
1685            err_msg.contains("nesting depth") || err_msg.contains("recursion"),
1686            "Expected recursion depth error, got: {}",
1687            err_msg
1688        );
1689    }
1690
1691    #[test]
1692    fn test_decode_allocation_limit() {
1693        // Create CBOR for a byte string claiming to be 200MB (exceeds default 100MB limit)
1694        let mut cbor = vec![0x5a]; // byte string with u32 length
1695        cbor.extend_from_slice(&200_000_000u32.to_be_bytes());
1696        // Don't actually include the bytes - the decoder should reject before reading them
1697
1698        let result: Result<Vec<u8>> = from_slice(&cbor);
1699        assert!(result.is_err());
1700        let err_msg = result.unwrap_err().to_string();
1701        assert!(
1702            err_msg.contains("Allocation") || err_msg.contains("exceeds maximum"),
1703            "Expected allocation limit error, got: {}",
1704            err_msg
1705        );
1706    }
1707
1708    #[test]
1709    fn test_decode_allocation_limit_custom() {
1710        use crate::decoder::from_slice_with_limit;
1711
1712        // Manually create CBOR claiming to have a 10KB byte string
1713        // Format: 0x5a (u32 length), then the length bytes
1714        let mut cbor = vec![0x5a]; // byte string with u32 length
1715        cbor.extend_from_slice(&10_000u32.to_be_bytes()); // Claims 10KB
1716        // Don't include all the bytes - just enough to show it would succeed with high limit
1717        cbor.extend_from_slice(&[0u8; 100]); // Only include 100 bytes
1718
1719        // This should succeed with a 20KB limit
1720        let result: Result<Vec<u8>> = from_slice_with_limit(&cbor, 20_000);
1721        // Will fail with "unexpected end" because we didn't include all bytes, but that's fine
1722        // The important thing is it doesn't fail with an allocation error
1723        assert!(result.is_err() && !result.unwrap_err().to_string().contains("exceeds maximum"));
1724
1725        // This should fail with allocation error for 5KB limit
1726        let mut cbor = vec![0x5a]; // byte string with u32 length
1727        cbor.extend_from_slice(&10_000u32.to_be_bytes()); // Claims 10KB
1728        let result: Result<Vec<u8>> = from_slice_with_limit(&cbor, 5_000);
1729        assert!(result.is_err());
1730        assert!(result.unwrap_err().to_string().contains("exceeds maximum"));
1731    }
1732
1733    #[test]
1734    fn test_decode_indefinite_byte_string() {
1735        use serde_bytes::ByteBuf;
1736        // Manually construct indefinite-length byte string
1737        // Format: 0x5f (indefinite bytes), chunks..., 0xff (break)
1738        let mut cbor = vec![0x5f]; // Start indefinite byte string
1739        cbor.push(0x43); // Definite byte string, length 3
1740        cbor.extend_from_slice(b"hel");
1741        cbor.push(0x42); // Definite byte string, length 2
1742        cbor.extend_from_slice(b"lo");
1743        cbor.push(0xff); // Break
1744
1745        let result: ByteBuf = from_slice(&cbor).unwrap();
1746        assert_eq!(result.as_ref(), b"hello");
1747    }
1748
1749    #[test]
1750    fn test_decode_indefinite_text_string() {
1751        // Manually construct indefinite-length text string
1752        // Format: 0x7f (indefinite text), chunks..., 0xff (break)
1753        let mut cbor = vec![0x7f]; // Start indefinite text string
1754        cbor.push(0x65); // Definite text string, length 5
1755        cbor.extend_from_slice(b"hello");
1756        cbor.push(0x61); // Definite text string, length 1
1757        cbor.extend_from_slice(b" ");
1758        cbor.push(0x65); // Definite text string, length 5
1759        cbor.extend_from_slice(b"world");
1760        cbor.push(0xff); // Break
1761
1762        let result: String = from_slice(&cbor).unwrap();
1763        assert_eq!(result, "hello world");
1764    }
1765
1766    #[test]
1767    fn test_decode_indefinite_array() {
1768        // Manually construct indefinite-length array
1769        // Format: 0x9f (indefinite array), elements..., 0xff (break)
1770        let mut cbor = vec![0x9f]; // Start indefinite array
1771        cbor.push(0x01); // integer 1
1772        cbor.push(0x02); // integer 2
1773        cbor.push(0x03); // integer 3
1774        cbor.push(0xff); // Break
1775
1776        let result: Vec<u32> = from_slice(&cbor).unwrap();
1777        assert_eq!(result, vec![1, 2, 3]);
1778    }
1779
1780    #[test]
1781    fn test_decode_indefinite_map() {
1782        use std::collections::HashMap;
1783
1784        // Manually construct indefinite-length map
1785        // Format: 0xbf (indefinite map), key-value pairs..., 0xff (break)
1786        let mut cbor = vec![0xbf]; // Start indefinite map
1787        // "a" => 1
1788        cbor.push(0x61);
1789        cbor.push(b'a');
1790        cbor.push(0x01);
1791        // "b" => 2
1792        cbor.push(0x61);
1793        cbor.push(b'b');
1794        cbor.push(0x02);
1795        cbor.push(0xff); // Break
1796
1797        let result: HashMap<String, u32> = from_slice(&cbor).unwrap();
1798        assert_eq!(result.len(), 2);
1799        assert_eq!(result.get("a"), Some(&1));
1800        assert_eq!(result.get("b"), Some(&2));
1801    }
1802
1803    #[test]
1804    fn test_decode_tagged_value() {
1805        // Test tag deserialization (tags are currently passed through to content)
1806        // Format: 0xc0 (tag 0), followed by value
1807        let mut cbor = vec![0xc0]; // Tag 0 (date/time string)
1808        cbor.push(0x64); // Text string, length 4
1809        cbor.extend_from_slice(b"test");
1810
1811        let result: String = from_slice(&cbor).unwrap();
1812        assert_eq!(result, "test");
1813    }
1814
1815    #[test]
1816    fn test_decode_enum_unit_variant() {
1817        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1818        enum TestEnum {
1819            VariantA,
1820            VariantB,
1821        }
1822
1823        let data = TestEnum::VariantA;
1824        let encoded = to_vec(&data).unwrap();
1825        let decoded: TestEnum = from_slice(&encoded).unwrap();
1826        assert_eq!(decoded, TestEnum::VariantA);
1827    }
1828
1829    #[test]
1830    fn test_decode_enum_newtype_variant() {
1831        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1832        enum TestEnum {
1833            Value(u32),
1834        }
1835
1836        let data = TestEnum::Value(42);
1837        let encoded = to_vec(&data).unwrap();
1838        let decoded: TestEnum = from_slice(&encoded).unwrap();
1839        assert_eq!(decoded, TestEnum::Value(42));
1840    }
1841
1842    #[test]
1843    fn test_decode_enum_tuple_variant() {
1844        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1845        enum TestEnum {
1846            Point(i32, i32),
1847        }
1848
1849        let data = TestEnum::Point(10, 20);
1850        let encoded = to_vec(&data).unwrap();
1851        let decoded: TestEnum = from_slice(&encoded).unwrap();
1852        assert_eq!(decoded, TestEnum::Point(10, 20));
1853    }
1854
1855    #[test]
1856    fn test_decode_enum_struct_variant() {
1857        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1858        enum TestEnum {
1859            Person { name: String, age: u32 },
1860        }
1861
1862        let data = TestEnum::Person {
1863            name: "Alice".to_string(),
1864            age: 30,
1865        };
1866        let encoded = to_vec(&data).unwrap();
1867        let decoded: TestEnum = from_slice(&encoded).unwrap();
1868        assert!(matches!(decoded, TestEnum::Person { .. }));
1869    }
1870
1871    #[test]
1872    fn test_decode_newtype_struct_array_format() {
1873        // Test NEW format: newtype struct as 1-element array
1874        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1875        struct Wrapped(String);
1876
1877        let data = Wrapped("test".to_string());
1878        let encoded = to_vec(&data).unwrap();
1879        let decoded: Wrapped = from_slice(&encoded).unwrap();
1880        assert_eq!(decoded, Wrapped("test".to_string()));
1881    }
1882
1883    #[test]
1884    fn test_decode_newtype_struct_transparent_format() {
1885        // Test OLD format compatibility: direct value (not wrapped in array)
1886        #[derive(Debug, Deserialize, PartialEq)]
1887        struct Wrapped(String);
1888
1889        // Manually encode as just a string (not in array)
1890        let cbor = to_vec(&"test".to_string()).unwrap();
1891        let decoded: Wrapped = from_slice(&cbor).unwrap();
1892        assert_eq!(decoded, Wrapped("test".to_string()));
1893    }
1894
1895    #[test]
1896    fn test_decode_option_some_various_types() {
1897        // Test Option<T> for various T types
1898        let some_int: Option<u32> = Some(42);
1899        let encoded = to_vec(&some_int).unwrap();
1900        let decoded: Option<u32> = from_slice(&encoded).unwrap();
1901        assert_eq!(decoded, Some(42));
1902
1903        let some_string: Option<String> = Some("hello".to_string());
1904        let encoded = to_vec(&some_string).unwrap();
1905        let decoded: Option<String> = from_slice(&encoded).unwrap();
1906        assert_eq!(decoded, Some("hello".to_string()));
1907
1908        let some_bytes: Option<Vec<u8>> = Some(vec![1, 2, 3]);
1909        let encoded = to_vec(&some_bytes).unwrap();
1910        let decoded: Option<Vec<u8>> = from_slice(&encoded).unwrap();
1911        assert_eq!(decoded, Some(vec![1, 2, 3]));
1912
1913        let some_bool: Option<bool> = Some(true);
1914        let encoded = to_vec(&some_bool).unwrap();
1915        let decoded: Option<bool> = from_slice(&encoded).unwrap();
1916        assert_eq!(decoded, Some(true));
1917    }
1918
1919    #[test]
1920    fn test_decode_option_none() {
1921        let none_int: Option<u32> = None;
1922        let encoded = to_vec(&none_int).unwrap();
1923        let decoded: Option<u32> = from_slice(&encoded).unwrap();
1924        assert_eq!(decoded, None);
1925    }
1926
1927    #[test]
1928    fn test_decode_from_reader() {
1929        use std::io::Cursor;
1930
1931        use crate::decoder::from_reader;
1932
1933        let data = vec![1u32, 2, 3, 4, 5];
1934        let encoded = to_vec(&data).unwrap();
1935        let reader = Cursor::new(encoded);
1936
1937        let decoded: Vec<u32> = from_reader(reader).unwrap();
1938        assert_eq!(decoded, vec![1, 2, 3, 4, 5]);
1939    }
1940
1941    #[test]
1942    fn test_decode_from_reader_with_limit() {
1943        use std::io::Cursor;
1944
1945        use crate::decoder::from_reader_with_limit;
1946
1947        // Manually create CBOR claiming to have a 10KB byte string
1948        let mut cbor = vec![0x5a]; // byte string with u32 length
1949        cbor.extend_from_slice(&10_000u32.to_be_bytes()); // Claims 10KB
1950        cbor.extend_from_slice(&[0u8; 100]); // Only include 100 bytes
1951
1952        // This should succeed with a 20KB limit (though it will fail with unexpected end)
1953        let reader = Cursor::new(cbor.clone());
1954        let result: Result<Vec<u8>> = from_reader_with_limit(reader, 20_000);
1955        assert!(result.is_err() && !result.unwrap_err().to_string().contains("exceeds maximum"));
1956
1957        // This should fail with allocation error for 5KB limit
1958        let reader = Cursor::new(cbor);
1959        let result: Result<Vec<u8>> = from_reader_with_limit(reader, 5_000);
1960        assert!(result.is_err());
1961        assert!(result.unwrap_err().to_string().contains("exceeds maximum"));
1962    }
1963
1964    #[test]
1965    fn test_decode_error_empty_input() {
1966        let empty: &[u8] = &[];
1967        let result: Result<u32> = from_slice(empty);
1968        assert!(result.is_err());
1969        assert!(result.unwrap_err().to_string().contains("empty"));
1970    }
1971
1972    #[test]
1973    fn test_decode_error_trailing_data() {
1974        // Encode an integer but add extra bytes
1975        let mut cbor = to_vec(&42u32).unwrap();
1976        cbor.push(0x00); // Extra byte
1977
1978        let result: Result<u32> = from_slice(&cbor);
1979        assert!(result.is_err());
1980        assert!(result.unwrap_err().to_string().contains("trailing"));
1981    }
1982
1983    #[test]
1984    fn test_decode_error_invalid_utf8() {
1985        // Manually create CBOR with invalid UTF-8 in text string
1986        let mut cbor = vec![0x64]; // Text string, length 4
1987        cbor.extend_from_slice(&[0xff, 0xfe, 0xfd, 0xfc]); // Invalid UTF-8
1988
1989        let result: Result<String> = from_slice(&cbor);
1990        assert!(result.is_err());
1991        let err_msg = result.unwrap_err().to_string();
1992        assert!(
1993            err_msg.contains("UTF-8") || err_msg.contains("utf8"),
1994            "Expected UTF-8 error, got: {}",
1995            err_msg
1996        );
1997    }
1998
1999    #[test]
2000    fn test_decode_error_wrong_enum_format() {
2001        // Try to decode an integer as an enum (should fail)
2002        let cbor = to_vec(&42u32).unwrap();
2003        #[derive(Deserialize)]
2004        enum TestEnum {
2005            A,
2006            B,
2007        }
2008        let result: Result<TestEnum> = from_slice(&cbor);
2009        assert!(result.is_err());
2010    }
2011
2012    #[test]
2013    fn test_decode_error_indefinite_in_chunks() {
2014        // Create invalid CBOR: indefinite byte string with indefinite chunk
2015        let mut cbor = vec![0x5f]; // Start indefinite byte string
2016        cbor.push(0x5f); // Invalid: chunk cannot be indefinite
2017        cbor.push(0x41);
2018        cbor.push(b'x');
2019        cbor.push(0xff); // break for inner
2020        cbor.push(0xff); // break for outer
2021
2022        let result: Result<Vec<u8>> = from_slice(&cbor);
2023        assert!(result.is_err());
2024    }
2025
2026    #[test]
2027    fn test_decode_error_wrong_chunk_type() {
2028        // Create invalid CBOR: indefinite byte string with text chunk
2029        let mut cbor = vec![0x5f]; // Start indefinite byte string
2030        cbor.push(0x61); // Invalid: text string chunk in byte string
2031        cbor.push(b'x');
2032        cbor.push(0xff); // break
2033
2034        let result: Result<Vec<u8>> = from_slice(&cbor);
2035        assert!(result.is_err());
2036        assert!(
2037            result
2038                .unwrap_err()
2039                .to_string()
2040                .contains("byte string chunks must be byte strings")
2041        );
2042    }
2043
2044    #[test]
2045    fn test_decode_error_indefinite_integer() {
2046        // Integers cannot be indefinite length
2047        let cbor = vec![0x1f]; // Invalid: indefinite unsigned integer
2048
2049        let result: Result<u32> = from_slice(&cbor);
2050        assert!(result.is_err());
2051    }
2052
2053    #[test]
2054    fn test_decode_bool_values() {
2055        // Test true
2056        let cbor = vec![0xf5]; // CBOR true
2057        let result: bool = from_slice(&cbor).unwrap();
2058        assert!(result);
2059
2060        // Test false
2061        let cbor = vec![0xf4]; // CBOR false
2062        let result: bool = from_slice(&cbor).unwrap();
2063        assert!(!result);
2064    }
2065
2066    #[test]
2067    fn test_decode_float_values() {
2068        // Test f32
2069        let val: f32 = 3.25;
2070        let encoded = to_vec(&val).unwrap();
2071        let decoded: f32 = from_slice(&encoded).unwrap();
2072        assert!((decoded - 3.25).abs() < 0.01);
2073
2074        // Test f64
2075        let val: f64 = 2.875;
2076        let encoded = to_vec(&val).unwrap();
2077        let decoded: f64 = from_slice(&encoded).unwrap();
2078        assert!((decoded - 2.875).abs() < 0.0001);
2079    }
2080
2081    #[test]
2082    fn test_decode_nested_structures() {
2083        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2084        struct Inner {
2085            value: u32,
2086        }
2087
2088        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2089        struct Middle {
2090            inner: Inner,
2091            name: String,
2092        }
2093
2094        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2095        struct Outer {
2096            middle: Middle,
2097            id: u64,
2098        }
2099
2100        let data = Outer {
2101            middle: Middle {
2102                inner: Inner { value: 42 },
2103                name: "test".to_string(),
2104            },
2105            id: 12345,
2106        };
2107
2108        let encoded = to_vec(&data).unwrap();
2109        let decoded: Outer = from_slice(&encoded).unwrap();
2110        assert_eq!(decoded, data);
2111    }
2112
2113    #[test]
2114    fn test_decode_tuple() {
2115        let data = (1u32, "hello".to_string(), true);
2116        let encoded = to_vec(&data).unwrap();
2117        let decoded: (u32, String, bool) = from_slice(&encoded).unwrap();
2118        assert_eq!(decoded, data);
2119    }
2120
2121    #[test]
2122    fn test_decode_char() {
2123        let data = 'x';
2124        let encoded = to_vec(&data).unwrap();
2125        let decoded: char = from_slice(&encoded).unwrap();
2126        assert_eq!(decoded, 'x');
2127    }
2128
2129    #[test]
2130    fn test_decode_definite_empty_collections() {
2131        // Empty array
2132        let empty_vec: Vec<u32> = vec![];
2133        let encoded = to_vec(&empty_vec).unwrap();
2134        let decoded: Vec<u32> = from_slice(&encoded).unwrap();
2135        assert_eq!(decoded, empty_vec);
2136
2137        // Empty map
2138        use std::collections::HashMap;
2139        let empty_map: HashMap<String, u32> = HashMap::new();
2140        let encoded = to_vec(&empty_map).unwrap();
2141        let decoded: HashMap<String, u32> = from_slice(&encoded).unwrap();
2142        assert_eq!(decoded.len(), 0);
2143    }
2144
2145    #[test]
2146    fn test_decode_indefinite_empty_collections() {
2147        // Empty indefinite array
2148        let cbor = vec![0x9f, 0xff]; // [_ break]
2149        let decoded: Vec<u32> = from_slice(&cbor).unwrap();
2150        assert_eq!(decoded.len(), 0);
2151
2152        // Empty indefinite map
2153        let cbor = vec![0xbf, 0xff]; // {_ break}
2154        use std::collections::HashMap;
2155        let decoded: HashMap<String, u32> = from_slice(&cbor).unwrap();
2156        assert_eq!(decoded.len(), 0);
2157    }
2158
2159    // Additional coverage tests for specific deserialize_any paths
2160
2161    #[test]
2162    fn test_decode_option_with_map() {
2163        use std::collections::HashMap;
2164
2165        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2166        struct Container {
2167            #[serde(skip_serializing_if = "Option::is_none")]
2168            data: Option<HashMap<String, u32>>,
2169        }
2170
2171        // Test Some(map)
2172        let mut map = HashMap::new();
2173        map.insert("key".to_string(), 42);
2174        let data = Container { data: Some(map) };
2175        let encoded = to_vec(&data).unwrap();
2176        let decoded: Container = from_slice(&encoded).unwrap();
2177        assert_eq!(decoded.data.unwrap().get("key"), Some(&42));
2178
2179        // Test None
2180        let data = Container { data: None };
2181        let encoded = to_vec(&data).unwrap();
2182        let decoded: Container = from_slice(&encoded).unwrap();
2183        assert_eq!(decoded.data, None);
2184    }
2185
2186    #[test]
2187    fn test_decode_option_with_array() {
2188        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2189        struct Container {
2190            #[serde(skip_serializing_if = "Option::is_none")]
2191            items: Option<Vec<i32>>,
2192        }
2193
2194        let data = Container {
2195            items: Some(vec![1, 2, 3]),
2196        };
2197        let encoded = to_vec(&data).unwrap();
2198        let decoded: Container = from_slice(&encoded).unwrap();
2199        assert_eq!(decoded.items, Some(vec![1, 2, 3]));
2200    }
2201
2202    #[test]
2203    fn test_decode_simple_types_coverage() {
2204        // Test MAJOR_SIMPLE paths for full coverage
2205
2206        // Boolean true/false already covered by test_decode_bool_values
2207
2208        // Test null as None
2209        let cbor = vec![0xf6]; // CBOR null
2210        let result: Option<String> = from_slice(&cbor).unwrap();
2211        assert_eq!(result, None);
2212    }
2213
2214    #[test]
2215    fn test_decode_indefinite_text_string_multipart() {
2216        // Test indefinite text string with multiple chunks
2217        let mut cbor = vec![0x7f]; // Start indefinite text
2218        cbor.push(0x62); // 2-byte string
2219        cbor.extend_from_slice(b"hi");
2220        cbor.push(0x63); // 3-byte string
2221        cbor.extend_from_slice(b"bye");
2222        cbor.push(0xff); // Break
2223
2224        let result: String = from_slice(&cbor).unwrap();
2225        assert_eq!(result, "hibye");
2226    }
2227
2228    #[test]
2229    fn test_decode_enum_with_map_variant() {
2230        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2231        enum TestEnum {
2232            Unit,
2233            Data(String),
2234        }
2235
2236        // Test enum variant as map (Data variant)
2237        let data = TestEnum::Data("content".to_string());
2238        let encoded = to_vec(&data).unwrap();
2239        let decoded: TestEnum = from_slice(&encoded).unwrap();
2240        assert_eq!(decoded, TestEnum::Data("content".to_string()));
2241
2242        // Test unit variant
2243        let data = TestEnum::Unit;
2244        let encoded = to_vec(&data).unwrap();
2245        let decoded: TestEnum = from_slice(&encoded).unwrap();
2246        assert_eq!(decoded, TestEnum::Unit);
2247    }
2248
2249    #[test]
2250    fn test_decode_tagged_recursive() {
2251        // Test MAJOR_TAG path that recursively calls deserialize_any
2252        // Tag 0 is typically used for date/time strings
2253        let mut cbor = vec![0xc0]; // Tag 0
2254        cbor.push(0x65); // 5-byte text string
2255        cbor.extend_from_slice(b"hello");
2256
2257        let result: String = from_slice(&cbor).unwrap();
2258        assert_eq!(result, "hello");
2259    }
2260
2261    #[test]
2262    fn test_decode_newtype_with_map_transparent() {
2263        use std::collections::HashMap;
2264
2265        #[derive(Debug, Deserialize, PartialEq)]
2266        struct Wrapper(HashMap<String, i32>);
2267
2268        // Test old transparent format (map encoded directly)
2269        let mut map = HashMap::new();
2270        map.insert("a".to_string(), 1);
2271        let cbor = to_vec(&map).unwrap();
2272
2273        let decoded: Wrapper = from_slice(&cbor).unwrap();
2274        assert_eq!(decoded.0.get("a"), Some(&1));
2275    }
2276
2277    #[test]
2278    fn test_decode_option_by_value_deserializer() {
2279        use std::collections::HashMap;
2280
2281        use crate::decoder::Decoder;
2282
2283        // Test the OptionDeserializer path (Decoder<R> by value, not &mut)
2284        // This triggers lines 193-255 in decoder.rs
2285
2286        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2287        struct TestStruct {
2288            #[serde(skip_serializing_if = "Option::is_none")]
2289            data: Option<HashMap<String, String>>,
2290        }
2291
2292        // Test with Some(map) - triggers definite-length map path
2293        let mut map = HashMap::new();
2294        map.insert("key".to_string(), "value".to_string());
2295        let test = TestStruct { data: Some(map) };
2296        let encoded = to_vec(&test).unwrap();
2297
2298        // Decode using Decoder directly (by value)
2299        let mut decoder = Decoder::from_slice(&encoded);
2300        let decoded: TestStruct = decoder.decode().unwrap();
2301        assert_eq!(
2302            decoded.data.as_ref().unwrap().get("key"),
2303            Some(&"value".to_string())
2304        );
2305
2306        // Test with indefinite-length map
2307        // Manually construct: {_ "data": {_ "k": "v", break}, break}
2308        let mut cbor = vec![0xbf]; // indefinite map
2309        cbor.extend_from_slice(b"\x64data"); // "data" key
2310        cbor.push(0xbf); // indefinite map value
2311        cbor.push(0x61); // 1-char key
2312        cbor.push(b'k');
2313        cbor.push(0x61); // 1-char value
2314        cbor.push(b'v');
2315        cbor.push(0xff); // break inner map
2316        cbor.push(0xff); // break outer map
2317
2318        let mut decoder = Decoder::from_slice(&cbor);
2319        let decoded: TestStruct = decoder.decode().unwrap();
2320        assert_eq!(
2321            decoded.data.as_ref().unwrap().get("k"),
2322            Some(&"v".to_string())
2323        );
2324    }
2325
2326    #[test]
2327    fn test_decode_by_value_all_types() {
2328        use serde::Deserialize;
2329
2330        use crate::decoder::Decoder;
2331
2332        // Test deserialize_any paths by consuming decoder (by value)
2333        // This should hit the Decoder<R> impl, not &mut Decoder<R>
2334
2335        // Test MAJOR_UNSIGNED
2336        let cbor = to_vec(&42u64).unwrap();
2337        let decoder = Decoder::from_slice(&cbor);
2338        let val = u64::deserialize(decoder).unwrap();
2339        assert_eq!(val, 42);
2340
2341        // Test MAJOR_NEGATIVE
2342        let cbor = to_vec(&-100i64).unwrap();
2343        let decoder = Decoder::from_slice(&cbor);
2344        let val = i64::deserialize(decoder).unwrap();
2345        assert_eq!(val, -100);
2346
2347        // Test MAJOR_BYTES (definite)
2348        let cbor = to_vec(&vec![1u8, 2, 3]).unwrap();
2349        let decoder = Decoder::from_slice(&cbor);
2350        let val = Vec::<u8>::deserialize(decoder).unwrap();
2351        assert_eq!(val, vec![1, 2, 3]);
2352
2353        // Test MAJOR_TEXT (definite)
2354        let cbor = to_vec(&"hello".to_string()).unwrap();
2355        let decoder = Decoder::from_slice(&cbor);
2356        let val = String::deserialize(decoder).unwrap();
2357        assert_eq!(val, "hello");
2358
2359        // Test MAJOR_ARRAY (definite)
2360        let cbor = to_vec(&vec![1u32, 2, 3]).unwrap();
2361        let decoder = Decoder::from_slice(&cbor);
2362        let val = Vec::<u32>::deserialize(decoder).unwrap();
2363        assert_eq!(val, vec![1, 2, 3]);
2364
2365        // Test MAJOR_MAP (definite)
2366        use std::collections::HashMap;
2367        let mut map = HashMap::new();
2368        map.insert("a".to_string(), 1u32);
2369        let cbor = to_vec(&map).unwrap();
2370        let decoder = Decoder::from_slice(&cbor);
2371        let val = HashMap::<String, u32>::deserialize(decoder).unwrap();
2372        assert_eq!(val.get("a"), Some(&1));
2373
2374        // Test MAJOR_TAG
2375        let mut cbor = vec![0xc0]; // Tag 0
2376        cbor.push(0x64); // 4-byte text
2377        cbor.extend_from_slice(b"test");
2378        let decoder = Decoder::from_slice(&cbor);
2379        let val = String::deserialize(decoder).unwrap();
2380        assert_eq!(val, "test");
2381
2382        // Test MAJOR_SIMPLE - bool true
2383        let cbor = vec![0xf5];
2384        let decoder = Decoder::from_slice(&cbor);
2385        let val = bool::deserialize(decoder).unwrap();
2386        assert!(val);
2387
2388        // Test MAJOR_SIMPLE - bool false
2389        let cbor = vec![0xf4];
2390        let decoder = Decoder::from_slice(&cbor);
2391        let val = bool::deserialize(decoder).unwrap();
2392        assert!(!val);
2393
2394        // Test MAJOR_SIMPLE - f32
2395        let cbor = to_vec(&3.25f32).unwrap();
2396        let decoder = Decoder::from_slice(&cbor);
2397        let val = f32::deserialize(decoder).unwrap();
2398        assert!((val - 3.25).abs() < 0.01);
2399
2400        // Test MAJOR_SIMPLE - f64
2401        let cbor = to_vec(&2.875f64).unwrap();
2402        let decoder = Decoder::from_slice(&cbor);
2403        let val = f64::deserialize(decoder).unwrap();
2404        assert!((val - 2.875).abs() < 0.0001);
2405    }
2406
2407    #[test]
2408    fn test_decode_enum_by_value() {
2409        use serde::Deserialize;
2410
2411        use crate::decoder::Decoder;
2412
2413        // Test deserialize_enum with by-value decoder
2414        // This hits lines 415-449 in decoder.rs
2415
2416        #[derive(Debug, Serialize, Deserialize, PartialEq)]
2417        enum TestEnum {
2418            Unit,
2419            Data(String),
2420        }
2421
2422        // Test MAJOR_TEXT path (unit variant)
2423        let cbor = to_vec(&TestEnum::Unit).unwrap();
2424        let decoder = Decoder::from_slice(&cbor);
2425        let val = TestEnum::deserialize(decoder).unwrap();
2426        assert_eq!(val, TestEnum::Unit);
2427
2428        // Test MAJOR_MAP path (variant with data)
2429        let cbor = to_vec(&TestEnum::Data("test".to_string())).unwrap();
2430        let decoder = Decoder::from_slice(&cbor);
2431        let val = TestEnum::deserialize(decoder).unwrap();
2432        assert_eq!(val, TestEnum::Data("test".to_string()));
2433    }
2434
2435    #[test]
2436    fn test_cbor_undefined_constant() {
2437        use crate::constants::UNDEFINED;
2438
2439        // Test that UNDEFINED constant is correct (additional info 23)
2440        // CBOR undefined is encoded as major type 7, additional info 23
2441        // Byte: 0xf7 = 0b111_10111 = major 7, info 23
2442        assert_eq!(UNDEFINED, 23);
2443
2444        // Manually construct CBOR undefined and verify encoding
2445        let cbor = [0xf7]; // Major type 7, additional info 23
2446
2447        // Note: serde doesn't have a concept of "undefined", so we can't
2448        // directly test deserialization. But we can verify the constant is correct.
2449        let major = cbor[0] >> 5;
2450        let info = cbor[0] & 0x1f;
2451        assert_eq!(major, 7);
2452        assert_eq!(info, UNDEFINED);
2453    }
2454
2455    #[test]
2456    fn test_cbor_float16_constant() {
2457        use crate::constants::FLOAT16;
2458
2459        // Test that FLOAT16 constant is correct (additional info 25)
2460        // CBOR float16 is encoded as major type 7, additional info 25
2461        // Byte: 0xf9 = 0b111_11001 = major 7, info 25
2462        assert_eq!(FLOAT16, 25);
2463
2464        // Manually construct CBOR float16 (1.0 in f16 = 0x3c00)
2465        // Format: 0xf9 (major 7, info 25) + 2 bytes for f16 value
2466        let cbor = vec![0xf9, 0x3c, 0x00];
2467
2468        let major = cbor[0] >> 5;
2469        let info = cbor[0] & 0x1f;
2470        assert_eq!(major, 7);
2471        assert_eq!(info, FLOAT16);
2472
2473        // Verify we can decode this as f64 (serde promotes f16 to f64)
2474        let result: Result<f64> = from_slice(&cbor);
2475        // Note: This may fail if decoder doesn't support f16 yet,
2476        // but the constant itself is correct
2477        if let Ok(val) = result {
2478            assert!((val - 1.0).abs() < 0.01);
2479        }
2480    }
2481
2482    #[test]
2483    fn test_cbor_simple_values_range() {
2484        use crate::constants::{FALSE, NULL, TRUE, UNDEFINED};
2485
2486        // Verify all simple values are in correct range (0-31)
2487        // These are the exact values defined in RFC 8949 section 3.3
2488        assert_eq!(FALSE, 20);
2489        assert_eq!(TRUE, 21);
2490        assert_eq!(NULL, 22);
2491        assert_eq!(UNDEFINED, 23);
2492
2493        // Note: All these values are < 32 by definition (5-bit additional info),
2494        // but clippy complains about assertions on constants, so we don't test that.
2495    }
2496
2497    #[test]
2498    fn test_decoder_with_limits() {
2499        use std::io::Cursor;
2500
2501        use crate::{DEFAULT_MAX_ALLOCATION, DEFAULT_MAX_DEPTH, Decoder};
2502
2503        // Test that default constants are re-exported and accessible
2504        assert_eq!(DEFAULT_MAX_ALLOCATION, 100 * 1024 * 1024);
2505        assert_eq!(DEFAULT_MAX_DEPTH, 128);
2506
2507        // Test Decoder builder with custom values
2508        let data = to_vec(&vec![1, 2, 3]).unwrap();
2509        let mut decoder = Decoder::new(Cursor::new(&data))
2510            .with_max_allocation(1024)
2511            .with_max_depth(32);
2512        let result: Vec<i32> = decoder.decode().unwrap();
2513        assert_eq!(result, vec![1, 2, 3]);
2514
2515        // Test that custom depth limit is enforced
2516        // Create nested arrays: [[[[...]]]] (40 levels deep)
2517        let mut nested_cbor = Vec::new();
2518        nested_cbor.extend(std::iter::repeat_n(0x81, 40)); // Array of length 1
2519        nested_cbor.push(0x00); // Final value: 0
2520
2521        // Should fail with max_depth of 32
2522        let mut decoder = Decoder::new(Cursor::new(&nested_cbor)).with_max_depth(32);
2523        let result: Result<Value> = decoder.decode();
2524        assert!(result.is_err());
2525        assert!(result.unwrap_err().to_string().contains("nesting depth"));
2526
2527        // Should succeed with max_depth of 64
2528        let mut decoder = Decoder::new(Cursor::new(&nested_cbor)).with_max_depth(64);
2529        let result: Result<Value> = decoder.decode();
2530        assert!(result.is_ok());
2531    }
2532
2533    #[test]
2534    fn test_max_allocation_indefinite_strings() {
2535        use std::io::Cursor;
2536
2537        use crate::Decoder;
2538
2539        // Test that indefinite byte strings respect cumulative allocation limit
2540        // Format: 0x5f (indefinite byte string) + chunks + 0xff (break)
2541        let mut cbor = vec![0x5f]; // Indefinite byte string start
2542
2543        // Add 3 chunks of 50 bytes each = 150 total
2544        for _ in 0..3 {
2545            cbor.push(0x58); // Major 2 (bytes), info 24 (1-byte length)
2546            cbor.push(50); // Length: 50 bytes
2547            cbor.extend(std::iter::repeat_n(0x42, 50)); // 50 bytes of data
2548        }
2549        cbor.push(0xff); // Break
2550
2551        // Should fail with 100-byte limit (total is 150)
2552        let mut decoder = Decoder::new(Cursor::new(&cbor)).with_max_allocation(100);
2553        let result: Result<Value> = decoder.decode();
2554        assert!(result.is_err());
2555        let err = result.unwrap_err().to_string();
2556        assert!(err.contains("total size") || err.contains("exceeds maximum"));
2557
2558        // Should succeed with 200-byte limit
2559        let mut decoder = Decoder::new(Cursor::new(&cbor)).with_max_allocation(200);
2560        let result: Result<Value> = decoder.decode();
2561        assert!(result.is_ok(), "Expected success with 200-byte limit");
2562        if let Value::Bytes(bytes) = result.unwrap() {
2563            assert_eq!(bytes.len(), 150);
2564        } else {
2565            panic!("Expected Value::Bytes");
2566        }
2567    }
2568
2569    #[test]
2570    fn test_max_allocation_single_large_allocation() {
2571        use std::io::Cursor;
2572
2573        use crate::Decoder;
2574
2575        // Test that a single large allocation is caught
2576        // Format: 0x5a (major 2, info 26 = 4-byte length) + length + data
2577        let mut cbor = vec![0x5a]; // Major 2 (bytes), info 26 (4-byte length)
2578        cbor.extend_from_slice(&1_000_000u32.to_be_bytes()); // 1MB
2579        cbor.extend(std::iter::repeat_n(0x42, 100)); // Just a bit of actual data
2580
2581        // Should fail with 100KB limit
2582        let mut decoder = Decoder::new(Cursor::new(&cbor)).with_max_allocation(100_000);
2583        let result: Result<Value> = decoder.decode();
2584        assert!(result.is_err());
2585        assert!(result.unwrap_err().to_string().contains("exceeds maximum"));
2586    }
2587
2588    #[test]
2589    fn test_u64_to_usize_overflow() {
2590        use std::io::Cursor;
2591
2592        use crate::Decoder;
2593
2594        // Test that u64 values that don't fit in usize are rejected
2595        // This is mainly relevant on 32-bit systems where usize is 32 bits
2596        // On 64-bit systems, this won't overflow, but the allocation check will catch it
2597
2598        // Create CBOR with a huge length value
2599        // Format: 0x5b (major 2, info 27 = 8-byte length) + 8-byte length + data
2600        let mut cbor = vec![0x5b]; // Major 2 (bytes), info 27 (8-byte length)
2601        cbor.extend_from_slice(&(u64::MAX).to_be_bytes()); // Massive length
2602
2603        let mut decoder = Decoder::new(Cursor::new(&cbor));
2604        let result: Result<Value> = decoder.decode();
2605        assert!(result.is_err());
2606        // Either caught by overflow check or allocation limit
2607        let err_str = result.unwrap_err().to_string();
2608        assert!(
2609            err_str.contains("exceeds maximum")
2610                || err_str.contains("out of memory")
2611                || err_str.contains("platform")
2612        );
2613    }
2614
2615    #[test]
2616    fn test_option_with_tagged_values() {
2617        use crate::tags::Tagged;
2618
2619        // Test Option<Tagged<String>> with tag using from_tagged_slice
2620        let tagged = Tagged::new(Some(0), "2024-01-15T10:30:00Z".to_string());
2621        let cbor = to_vec(&tagged).unwrap();
2622        let decoded = Tagged::<String>::from_tagged_slice(&cbor).unwrap();
2623        assert_eq!(decoded.tag, Some(0));
2624        assert_eq!(decoded.value, "2024-01-15T10:30:00Z");
2625
2626        // Test that transparent mode works in Options (tag is ignored)
2627        let some_tagged = Some(Tagged::new(Some(32), "https://example.com".to_string()));
2628        let cbor = to_vec(&some_tagged).unwrap();
2629        let decoded: Option<Tagged<String>> = from_slice(&cbor).unwrap();
2630        // With transparent mode, tag is lost but value is preserved
2631        assert_eq!(
2632            decoded.as_ref().map(|t| &t.value),
2633            Some(&"https://example.com".to_string())
2634        );
2635
2636        // Test Option with None
2637        let none: Option<Tagged<String>> = None;
2638        let cbor = to_vec(&none).unwrap();
2639        let decoded: Option<Tagged<String>> = from_slice(&cbor).unwrap();
2640        assert_eq!(decoded, None);
2641    }
2642
2643    #[test]
2644    fn test_option_with_arrays() {
2645        // Test Option<Vec<i32>>
2646        let some_vec = Some(vec![1, 2, 3]);
2647        let cbor = to_vec(&some_vec).unwrap();
2648        let decoded: Option<Vec<i32>> = from_slice(&cbor).unwrap();
2649        assert_eq!(decoded, some_vec);
2650
2651        // Test None
2652        let none: Option<Vec<i32>> = None;
2653        let cbor = to_vec(&none).unwrap();
2654        let decoded: Option<Vec<i32>> = from_slice(&cbor).unwrap();
2655        assert_eq!(decoded, None);
2656    }
2657
2658    #[test]
2659    fn test_option_with_maps() {
2660        use std::collections::HashMap;
2661
2662        // Test Option<HashMap<String, i32>>
2663        let mut map = HashMap::new();
2664        map.insert("a".to_string(), 1);
2665        map.insert("b".to_string(), 2);
2666        let some_map = Some(map.clone());
2667        let cbor = to_vec(&some_map).unwrap();
2668        let decoded: Option<HashMap<String, i32>> = from_slice(&cbor).unwrap();
2669        assert_eq!(decoded, some_map);
2670
2671        // Test None
2672        let none: Option<HashMap<String, i32>> = None;
2673        let cbor = to_vec(&none).unwrap();
2674        let decoded: Option<HashMap<String, i32>> = from_slice(&cbor).unwrap();
2675        assert_eq!(decoded, None);
2676    }
2677
2678    #[test]
2679    fn test_option_with_struct() {
2680        #[derive(Debug, PartialEq, Serialize, Deserialize)]
2681        struct Person {
2682            name: String,
2683            age: u32,
2684        }
2685
2686        // Test Option<struct>
2687        let person = Some(Person {
2688            name: "Alice".to_string(),
2689            age: 30,
2690        });
2691        let cbor = to_vec(&person).unwrap();
2692        let decoded: Option<Person> = from_slice(&cbor).unwrap();
2693        assert_eq!(decoded, person);
2694
2695        // Test None
2696        let none: Option<Person> = None;
2697        let cbor = to_vec(&none).unwrap();
2698        let decoded: Option<Person> = from_slice(&cbor).unwrap();
2699        assert_eq!(decoded, None);
2700    }
2701}