senax_encoder/
core.rs

1//! Type tags used in the senax binary format.
2//!
3//! These tags are written as the first byte of each encoded value to identify its type and optimize decoding.
4//! Most users do not need to use these directly.
5//!
6//! - Primitives, Option, String, Vec, arrays, maps, structs, enums, and feature types each have their own tag(s).
7//! - Tags are stable and part of the wire format.
8
9use crate::*;
10
11///< 0 for numbers, false for bool
12pub const TAG_ZERO: u8 = 0;
13///< 1 for numbers, true for bool
14// 5-130: Values 2-127 (compact encoding for small unsigned integers)
15pub const TAG_ONE: u8 = 1;
16pub const TAG_U8_127: u8 = 127; // 127
17pub const TAG_NONE: u8 = 128;
18pub const TAG_SOME: u8 = 129;
19pub const TAG_U8: u8 = 131;
20pub const TAG_U16: u8 = 132;
21pub const TAG_U32: u8 = 133;
22pub const TAG_U64: u8 = 134;
23pub const TAG_U128: u8 = 135;
24///< Negative signed integer (bit-inverted encoding)
25pub const TAG_NEGATIVE: u8 = 136;
26pub const TAG_F32: u8 = 137;
27pub const TAG_F64: u8 = 138;
28///< Short string (length in tag) - String, SmolStr
29pub const TAG_STRING_BASE: u8 = 139;
30///< Long string (length encoded) - String, SmolStr
31pub const TAG_STRING_LONG: u8 = 180;
32///< Bytes
33pub const TAG_BINARY: u8 = 181;
34///< Unit struct
35pub const TAG_STRUCT_UNIT: u8 = 182;
36///< Named struct
37pub const TAG_STRUCT_NAMED: u8 = 183;
38///< Tuple struct
39pub const TAG_STRUCT_UNNAMED: u8 = 184;
40pub const TAG_ENUM: u8 = 185;
41///< Enum with named fields
42pub const TAG_ENUM_NAMED: u8 = 186;
43///< Enum with tuple fields
44pub const TAG_ENUM_UNNAMED: u8 = 187;
45///< Short array/vec/set (length in tag) - includes HashSet, BTreeSet, IndexSet, FxHashSet, AHashSet
46pub const TAG_ARRAY_VEC_SET_BASE: u8 = 188;
47///< Long array/vec/set (length encoded) - includes HashSet, BTreeSet, IndexSet, FxHashSet, AHashSet
48pub const TAG_ARRAY_VEC_SET_LONG: u8 = 194;
49///< Tuple
50pub const TAG_TUPLE: u8 = 195;
51///< Map (HashMap, BTreeMap, IndexMap, FxHashMap, AHashMap)
52pub const TAG_MAP: u8 = 196;
53///< chrono::DateTime
54pub const TAG_CHRONO_DATETIME: u8 = 197;
55///< chrono::NaiveDate
56pub const TAG_CHRONO_NAIVE_DATE: u8 = 198;
57///< chrono::NaiveTime
58pub const TAG_CHRONO_NAIVE_TIME: u8 = 199;
59///< chrono::NaiveDateTime
60pub const TAG_CHRONO_NAIVE_DATETIME: u8 = 208;
61///< rust_decimal::Decimal
62pub const TAG_DECIMAL: u8 = 200;
63///< uuid::Uuid, ulid::Ulid
64pub const TAG_UUID: u8 = 201;
65pub const TAG_JSON_NULL: u8 = 202;
66pub const TAG_JSON_BOOL: u8 = 203; // Uses existing TAG_ZERO/TAG_ONE for value
67pub const TAG_JSON_NUMBER: u8 = 204;
68pub const TAG_JSON_STRING: u8 = 205; // Uses existing string encoding
69pub const TAG_JSON_ARRAY: u8 = 206;
70pub const TAG_JSON_OBJECT: u8 = 207;
71
72// --- bool ---
73/// Encodes a `bool` as a single tag byte: `TAG_ZERO` for `false`, `TAG_ONE` for `true`.
74impl Encoder for bool {
75    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
76        let tag = if !*self { TAG_ZERO } else { TAG_ONE }; // 0: false, 1: true
77        writer.put_u8(tag);
78        Ok(())
79    }
80
81    fn is_default(&self) -> bool {
82        !(*self)
83    }
84}
85
86/// Packs a `bool` as a single tag byte: `TAG_ZERO` for `false`, `TAG_ONE` for `true`.
87impl Packer for bool {
88    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
89        let tag = if !*self { TAG_ZERO } else { TAG_ONE }; // 0: false, 1: true
90        writer.put_u8(tag);
91        Ok(())
92    }
93}
94
95/// Decodes a `bool` from a single tag byte.
96///
97/// # Errors
98/// Returns an error if the tag is not `TAG_ZERO` or `TAG_ONE`.
99impl Decoder for bool {
100    fn decode(reader: &mut Bytes) -> Result<Self> {
101        if reader.remaining() == 0 {
102            return Err(EncoderError::InsufficientData);
103        }
104        let tag = reader.get_u8();
105        match tag {
106            TAG_ZERO => Ok(false),
107            TAG_ONE => Ok(true),
108            other => Err(EncoderError::Decode(format!(
109                "Expected bool tag ({} or {}), got {}",
110                TAG_ZERO, TAG_ONE, other
111            ))),
112        }
113    }
114}
115
116/// Unpacks a `bool` from a single byte with relaxed validation.
117///
118/// 0 is interpreted as `false`, any non-zero value is interpreted as `true`.
119/// No error checking is performed for invalid values.
120impl Unpacker for bool {
121    fn unpack(reader: &mut Bytes) -> Result<Self> {
122        if reader.remaining() == 0 {
123            return Err(EncoderError::InsufficientData);
124        }
125        let value = reader.get_u8();
126        Ok(value != TAG_ZERO)
127    }
128}
129
130// --- Common decode functions ---
131/// Decodes a `u8` value from a tag and buffer.
132/// Used internally for compact integer decoding.
133///
134/// # Errors
135/// Returns an error if the tag is not valid for a `u8`.
136#[inline]
137fn decode_u8_from_tag(tag: u8, reader: &mut Bytes) -> Result<u8> {
138    if (TAG_ZERO..=TAG_U8_127).contains(&tag) {
139        Ok(tag - TAG_ZERO)
140    } else if tag == TAG_U8 {
141        if reader.remaining() == 0 {
142            return Err(EncoderError::InsufficientData);
143        }
144        let stored_val = reader.get_u8();
145        stored_val.checked_add(128).ok_or_else(|| {
146            EncoderError::Decode(format!("u8 TAG_U8 value overflow: {}", stored_val))
147        })
148    } else {
149        Err(EncoderError::Decode(format!(
150            "Unexpected tag for u8: {}",
151            tag
152        )))
153    }
154}
155/// Decodes a `u16` value from a tag and buffer.
156/// Used internally for compact integer decoding.
157fn decode_u16_from_tag(tag: u8, reader: &mut Bytes) -> Result<u16> {
158    if (TAG_ZERO..=TAG_U8_127).contains(&tag) {
159        Ok((tag - TAG_ZERO) as u16)
160    } else if tag == TAG_U8 {
161        if reader.remaining() == 0 {
162            return Err(EncoderError::InsufficientData);
163        }
164        Ok(reader.get_u8() as u16 + 128)
165    } else if tag == TAG_U16 {
166        if reader.remaining() < 2 {
167            return Err(EncoderError::InsufficientData);
168        }
169        Ok(reader.get_u16_le())
170    } else {
171        Err(EncoderError::Decode(format!(
172            "Unexpected tag for u16: {}",
173            tag
174        )))
175    }
176}
177/// Decodes a `u32` value from a tag and buffer.
178/// Used internally for compact integer decoding.
179#[inline]
180fn decode_u32_from_tag(tag: u8, reader: &mut Bytes) -> Result<u32> {
181    if (TAG_ZERO..=TAG_U8_127).contains(&tag) {
182        Ok((tag - TAG_ZERO) as u32)
183    } else if tag == TAG_U8 {
184        if reader.remaining() == 0 {
185            return Err(EncoderError::InsufficientData);
186        }
187        Ok(reader.get_u8() as u32 + 128)
188    } else if tag == TAG_U16 {
189        if reader.remaining() < 2 {
190            return Err(EncoderError::InsufficientData);
191        }
192        Ok(reader.get_u16_le() as u32)
193    } else if tag == TAG_U32 {
194        if reader.remaining() < 4 {
195            return Err(EncoderError::InsufficientData);
196        }
197        Ok(reader.get_u32_le())
198    } else {
199        Err(EncoderError::Decode(format!(
200            "Unexpected tag for u32: {}",
201            tag
202        )))
203    }
204}
205/// Decodes a `u64` value from a tag and buffer.
206/// Used internally for compact integer decoding.
207#[inline]
208fn decode_u64_from_tag(tag: u8, reader: &mut Bytes) -> Result<u64> {
209    if (TAG_ZERO..=TAG_U8_127).contains(&tag) {
210        Ok((tag - TAG_ZERO) as u64)
211    } else if tag == TAG_U8 {
212        if reader.remaining() == 0 {
213            return Err(EncoderError::InsufficientData);
214        }
215        Ok(reader.get_u8() as u64 + 128)
216    } else if tag == TAG_U16 {
217        if reader.remaining() < 2 {
218            return Err(EncoderError::InsufficientData);
219        }
220        Ok(reader.get_u16_le() as u64)
221    } else if tag == TAG_U32 {
222        if reader.remaining() < 4 {
223            return Err(EncoderError::InsufficientData);
224        }
225        Ok(reader.get_u32_le() as u64)
226    } else if tag == TAG_U64 {
227        if reader.remaining() < 8 {
228            return Err(EncoderError::InsufficientData);
229        }
230        Ok(reader.get_u64_le())
231    } else {
232        Err(EncoderError::Decode(format!(
233            "Unexpected tag for u64: {}",
234            tag
235        )))
236    }
237}
238/// Decodes a `u128` value from a tag and buffer.
239/// Used internally for compact integer decoding.
240fn decode_u128_from_tag(tag: u8, reader: &mut Bytes) -> Result<u128> {
241    if (TAG_ZERO..=TAG_U8_127).contains(&tag) {
242        Ok((tag - TAG_ZERO) as u128)
243    } else if tag == TAG_U8 {
244        if reader.remaining() == 0 {
245            return Err(EncoderError::InsufficientData);
246        }
247        Ok(reader.get_u8() as u128 + 128)
248    } else if tag == TAG_U16 {
249        if reader.remaining() < 2 {
250            return Err(EncoderError::InsufficientData);
251        }
252        Ok(reader.get_u16_le() as u128)
253    } else if tag == TAG_U32 {
254        if reader.remaining() < 4 {
255            return Err(EncoderError::InsufficientData);
256        }
257        Ok(reader.get_u32_le() as u128)
258    } else if tag == TAG_U64 {
259        if reader.remaining() < 8 {
260            return Err(EncoderError::InsufficientData);
261        }
262        Ok(reader.get_u64_le() as u128)
263    } else if tag == TAG_U128 {
264        if reader.remaining() < 16 {
265            return Err(EncoderError::InsufficientData);
266        }
267        Ok(reader.get_u128_le())
268    } else {
269        Err(EncoderError::Decode(format!(
270            "Unexpected tag for u128: {}",
271            tag
272        )))
273    }
274}
275
276// --- Unsigned integer types ---
277/// Encodes unsigned integers using a compact variable-length format.
278///
279/// - Values 0/1 are encoded as `TAG_ZERO`/`TAG_ONE` (1 byte)
280/// - 2..=127 are encoded as a single tag byte (1 byte)
281/// - Larger values use `TAG_U8`, `TAG_U16`, `TAG_U32`, `TAG_U64`, or `TAG_U128` with the value in little-endian
282/// - The encoding is stable and compatible across platforms
283impl Encoder for u8 {
284    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
285        if *self <= 127 {
286            writer.put_u8(TAG_ZERO + *self);
287        } else {
288            writer.put_u8(TAG_U8);
289            writer.put_u8(*self - 128);
290        }
291        Ok(())
292    }
293
294    fn is_default(&self) -> bool {
295        *self == 0
296    }
297}
298
299impl Packer for u8 {
300    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
301        writer.put_u8(*self);
302        Ok(())
303    }
304}
305
306/// Decodes a `u8` from the compact format.
307impl Decoder for u8 {
308    fn decode(reader: &mut Bytes) -> Result<Self> {
309        if reader.remaining() == 0 {
310            return Err(EncoderError::InsufficientData);
311        }
312        let tag = reader.get_u8();
313        decode_u8_from_tag(tag, reader)
314    }
315}
316
317impl Unpacker for u8 {
318    fn unpack(reader: &mut Bytes) -> Result<Self> {
319        if reader.remaining() == 0 {
320            return Err(EncoderError::InsufficientData);
321        }
322        Ok(reader.get_u8())
323    }
324}
325
326/// See `u8` for format details.
327impl Encoder for u16 {
328    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
329        if *self <= 127 {
330            writer.put_u8(TAG_ZERO + (*self as u8));
331        } else if *self <= 255 + 128 {
332            writer.put_u8(TAG_U8);
333            writer.put_u8((*self - 128) as u8);
334        } else {
335            writer.put_u8(TAG_U16);
336            writer.put_u16_le(*self);
337        }
338        Ok(())
339    }
340
341    fn is_default(&self) -> bool {
342        *self == 0
343    }
344}
345
346impl Packer for u16 {
347    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
348        self.encode(writer)
349    }
350}
351
352impl Decoder for u16 {
353    fn decode(reader: &mut Bytes) -> Result<Self> {
354        if reader.remaining() == 0 {
355            return Err(EncoderError::InsufficientData);
356        }
357        let tag = reader.get_u8();
358        decode_u16_from_tag(tag, reader)
359    }
360}
361
362impl Unpacker for u16 {
363    fn unpack(reader: &mut Bytes) -> Result<Self> {
364        Self::decode(reader)
365    }
366}
367
368impl Encoder for u32 {
369    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
370        if *self <= 127 {
371            writer.put_u8(TAG_ZERO + (*self as u8));
372        } else if *self <= 255 + 128 {
373            writer.put_u8(TAG_U8);
374            writer.put_u8((*self - 128) as u8);
375        } else if *self <= 65535 {
376            writer.put_u8(TAG_U16);
377            writer.put_u16_le(*self as u16);
378        } else {
379            writer.put_u8(TAG_U32);
380            writer.put_u32_le(*self);
381        }
382        Ok(())
383    }
384
385    fn is_default(&self) -> bool {
386        *self == 0
387    }
388}
389
390impl Packer for u32 {
391    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
392        self.encode(writer)
393    }
394}
395
396/// Decodes a `u32` from the compact format.
397impl Decoder for u32 {
398    fn decode(reader: &mut Bytes) -> Result<Self> {
399        if reader.remaining() == 0 {
400            return Err(EncoderError::InsufficientData);
401        }
402        let tag = reader.get_u8();
403        decode_u32_from_tag(tag, reader)
404    }
405}
406
407impl Unpacker for u32 {
408    fn unpack(reader: &mut Bytes) -> Result<Self> {
409        Self::decode(reader)
410    }
411}
412
413/// See `u32` for format details.
414impl Encoder for u64 {
415    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
416        if *self <= 127 {
417            writer.put_u8(TAG_ZERO + (*self as u8));
418        } else if *self <= 255 + 128 {
419            writer.put_u8(TAG_U8);
420            writer.put_u8((*self - 128) as u8);
421        } else if *self <= 65535 {
422            writer.put_u8(TAG_U16);
423            writer.put_u16_le(*self as u16);
424        } else if *self <= 4294967295 {
425            writer.put_u8(TAG_U32);
426            writer.put_u32_le(*self as u32);
427        } else {
428            writer.put_u8(TAG_U64);
429            writer.put_u64_le(*self);
430        }
431        Ok(())
432    }
433
434    fn is_default(&self) -> bool {
435        *self == 0
436    }
437}
438
439impl Packer for u64 {
440    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
441        self.encode(writer)
442    }
443}
444
445/// Decodes a `u64` from the compact format.
446impl Decoder for u64 {
447    fn decode(reader: &mut Bytes) -> Result<Self> {
448        if reader.remaining() == 0 {
449            return Err(EncoderError::InsufficientData);
450        }
451        let tag = reader.get_u8();
452        decode_u64_from_tag(tag, reader)
453    }
454}
455
456impl Unpacker for u64 {
457    fn unpack(reader: &mut Bytes) -> Result<Self> {
458        Self::decode(reader)
459    }
460}
461
462/// See `u64` for format details.
463impl Encoder for u128 {
464    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
465        if *self <= 127 {
466            writer.put_u8(TAG_ZERO + (*self as u8));
467        } else if *self <= 255 + 128 {
468            writer.put_u8(TAG_U8);
469            writer.put_u8((*self - 128) as u8);
470        } else if *self <= 65535 {
471            writer.put_u8(TAG_U16);
472            writer.put_u16_le(*self as u16);
473        } else if *self <= 4294967295 {
474            writer.put_u8(TAG_U32);
475            writer.put_u32_le(*self as u32);
476        } else if *self <= 18446744073709551615 {
477            writer.put_u8(TAG_U64);
478            writer.put_u64_le(*self as u64);
479        } else {
480            writer.put_u8(TAG_U128);
481            writer.put_u128_le(*self);
482        }
483        Ok(())
484    }
485
486    fn is_default(&self) -> bool {
487        *self == 0
488    }
489}
490
491impl Packer for u128 {
492    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
493        self.encode(writer)
494    }
495}
496
497impl Decoder for u128 {
498    fn decode(reader: &mut Bytes) -> Result<Self> {
499        if reader.remaining() == 0 {
500            return Err(EncoderError::InsufficientData);
501        }
502        let tag = reader.get_u8();
503        decode_u128_from_tag(tag, reader)
504    }
505}
506
507impl Unpacker for u128 {
508    fn unpack(reader: &mut Bytes) -> Result<Self> {
509        Self::decode(reader)
510    }
511}
512
513/// Encodes `usize` using the platform's pointer width, but always as a portable integer format.
514impl Encoder for usize {
515    #[inline]
516    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
517        if usize::BITS == u64::BITS {
518            let v = *self as u64;
519            v.encode(writer)
520        } else if usize::BITS == u32::BITS {
521            let v = *self as u32;
522            v.encode(writer)
523        } else if usize::BITS == u16::BITS {
524            let v = *self as u16;
525            v.encode(writer)
526        } else {
527            let v = *self as u128;
528            v.encode(writer)
529        }
530    }
531
532    fn is_default(&self) -> bool {
533        *self == 0
534    }
535}
536
537impl Packer for usize {
538    #[inline]
539    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
540        self.encode(writer)
541    }
542}
543
544impl Decoder for usize {
545    fn decode(reader: &mut Bytes) -> Result<Self> {
546        if reader.remaining() == 0 {
547            return Err(EncoderError::InsufficientData);
548        }
549        let tag = reader.get_u8();
550        if usize::BITS == u64::BITS {
551            Ok(decode_u64_from_tag(tag, reader)? as usize)
552        } else if usize::BITS == u32::BITS {
553            Ok(decode_u32_from_tag(tag, reader)? as usize)
554        } else if usize::BITS == u16::BITS {
555            Ok(decode_u16_from_tag(tag, reader)? as usize)
556        } else {
557            Ok(decode_u128_from_tag(tag, reader)? as usize)
558        }
559    }
560}
561
562impl Unpacker for usize {
563    fn unpack(reader: &mut Bytes) -> Result<Self> {
564        Self::decode(reader)
565    }
566}
567
568// --- Signed integer types (bit-inverted encoding) ---
569/// Encodes signed integers using bit-inverted encoding for negative values.
570///
571/// - Non-negative values (>= 0) are encoded as unsigned integers
572/// - Negative values use `TAG_NEGATIVE` and bit-inverted encoding
573impl Encoder for i8 {
574    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
575        if *self >= 0 {
576            (*self as u8).encode(writer)
577        } else {
578            writer.put_u8(TAG_NEGATIVE);
579            let inv = !(*self as u8);
580            inv.encode(writer)
581        }
582    }
583
584    fn is_default(&self) -> bool {
585        *self == 0
586    }
587}
588
589impl Packer for i8 {
590    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
591        writer.put_i8(*self);
592        Ok(())
593    }
594}
595
596/// Decodes a `i8` from the bit-inverted encoding.
597///
598/// # Errors
599/// Returns an error if the tag is not valid for an `i8`.
600impl Decoder for i8 {
601    fn decode(reader: &mut Bytes) -> Result<Self> {
602        if reader.remaining() == 0 {
603            return Err(EncoderError::InsufficientData);
604        }
605        let tag = reader.get_u8();
606        match tag {
607            TAG_NEGATIVE => {
608                let inv = u8::decode(reader)?;
609                Ok(!inv as i8)
610            }
611            t => {
612                let v = decode_u8_from_tag(t, reader)?;
613                if v > i8::MAX as u8 {
614                    return Err(EncoderError::Decode(format!(
615                        "Value {} too large for i8",
616                        v
617                    )));
618                }
619                Ok(v as i8)
620            }
621        }
622    }
623}
624
625impl Unpacker for i8 {
626    fn unpack(reader: &mut Bytes) -> Result<Self> {
627        if reader.remaining() == 0 {
628            return Err(EncoderError::InsufficientData);
629        }
630        Ok(reader.get_i8())
631    }
632}
633// i16
634impl Encoder for i16 {
635    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
636        if *self >= 0 {
637            (*self as u16).encode(writer)
638        } else {
639            writer.put_u8(TAG_NEGATIVE);
640            let inv = !(*self as u16);
641            inv.encode(writer)
642        }
643    }
644
645    fn is_default(&self) -> bool {
646        *self == 0
647    }
648}
649
650impl Packer for i16 {
651    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
652        self.encode(writer)
653    }
654}
655
656impl Decoder for i16 {
657    fn decode(reader: &mut Bytes) -> Result<Self> {
658        if reader.remaining() == 0 {
659            return Err(EncoderError::InsufficientData);
660        }
661        let tag = reader.get_u8();
662        match tag {
663            TAG_NEGATIVE => {
664                let inv = u16::decode(reader)?;
665                Ok(!inv as i16)
666            }
667            t => {
668                let v = decode_u16_from_tag(t, reader)?;
669                if v > i16::MAX as u16 {
670                    return Err(EncoderError::Decode(format!(
671                        "Value {} too large for i16",
672                        v
673                    )));
674                }
675                Ok(v as i16)
676            }
677        }
678    }
679}
680
681impl Unpacker for i16 {
682    fn unpack(reader: &mut Bytes) -> Result<Self> {
683        Self::decode(reader)
684    }
685}
686// i32
687impl Encoder for i32 {
688    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
689        if *self >= 0 {
690            (*self as u32).encode(writer)
691        } else {
692            writer.put_u8(TAG_NEGATIVE);
693            let inv = !(*self as u32);
694            inv.encode(writer)
695        }
696    }
697
698    fn is_default(&self) -> bool {
699        *self == 0
700    }
701}
702
703impl Packer for i32 {
704    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
705        self.encode(writer)
706    }
707}
708
709impl Decoder for i32 {
710    fn decode(reader: &mut Bytes) -> Result<Self> {
711        if reader.remaining() == 0 {
712            return Err(EncoderError::InsufficientData);
713        }
714        let tag = reader.get_u8();
715        match tag {
716            TAG_NEGATIVE => {
717                let inv = u32::decode(reader)?;
718                Ok(!inv as i32)
719            }
720            t => {
721                let v = decode_u32_from_tag(t, reader)?;
722                if v > i32::MAX as u32 {
723                    return Err(EncoderError::Decode(format!(
724                        "Value {} too large for i32",
725                        v
726                    )));
727                }
728                Ok(v as i32)
729            }
730        }
731    }
732}
733
734impl Unpacker for i32 {
735    fn unpack(reader: &mut Bytes) -> Result<Self> {
736        Self::decode(reader)
737    }
738}
739
740// i64
741impl Encoder for i64 {
742    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
743        if *self >= 0 {
744            (*self as u64).encode(writer)
745        } else {
746            writer.put_u8(TAG_NEGATIVE);
747            let inv = !(*self as u64);
748            inv.encode(writer)
749        }
750    }
751
752    fn is_default(&self) -> bool {
753        *self == 0
754    }
755}
756
757impl Packer for i64 {
758    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
759        self.encode(writer)
760    }
761}
762
763impl Decoder for i64 {
764    fn decode(reader: &mut Bytes) -> Result<Self> {
765        if reader.remaining() == 0 {
766            return Err(EncoderError::InsufficientData);
767        }
768        let tag = reader.get_u8();
769        match tag {
770            TAG_NEGATIVE => {
771                let inv = u64::decode(reader)?;
772                Ok(!inv as i64)
773            }
774            t => {
775                let v = decode_u64_from_tag(t, reader)?;
776                if v > i64::MAX as u64 {
777                    return Err(EncoderError::Decode(format!(
778                        "Value {} too large for i64",
779                        v
780                    )));
781                }
782                Ok(v as i64)
783            }
784        }
785    }
786}
787
788impl Unpacker for i64 {
789    fn unpack(reader: &mut Bytes) -> Result<Self> {
790        Self::decode(reader)
791    }
792}
793
794// i128
795impl Encoder for i128 {
796    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
797        if *self >= 0 {
798            (*self as u128).encode(writer)
799        } else {
800            writer.put_u8(TAG_NEGATIVE);
801            let inv = !(*self as u128);
802            inv.encode(writer)
803        }
804    }
805
806    fn is_default(&self) -> bool {
807        *self == 0
808    }
809}
810
811impl Packer for i128 {
812    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
813        self.encode(writer)
814    }
815}
816
817impl Decoder for i128 {
818    fn decode(reader: &mut Bytes) -> Result<Self> {
819        if reader.remaining() == 0 {
820            return Err(EncoderError::InsufficientData);
821        }
822        let tag = reader.get_u8();
823        match tag {
824            TAG_NEGATIVE => {
825                let inv = u128::decode(reader)?;
826                Ok(!inv as i128)
827            }
828            t => {
829                let v = decode_u128_from_tag(t, reader)?;
830                if v > i128::MAX as u128 {
831                    return Err(EncoderError::Decode(format!(
832                        "Value {} too large for i128",
833                        v
834                    )));
835                }
836                Ok(v as i128)
837            }
838        }
839    }
840}
841
842impl Unpacker for i128 {
843    fn unpack(reader: &mut Bytes) -> Result<Self> {
844        Self::decode(reader)
845    }
846}
847
848// isize
849impl Encoder for isize {
850    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
851        if usize::BITS == u64::BITS {
852            let v = *self as i64;
853            v.encode(writer)
854        } else if usize::BITS == u32::BITS {
855            let v = *self as i32;
856            v.encode(writer)
857        } else if usize::BITS == u16::BITS {
858            let v = *self as i16;
859            v.encode(writer)
860        } else {
861            let v = *self as i128;
862            v.encode(writer)
863        }
864    }
865
866    fn is_default(&self) -> bool {
867        *self == 0
868    }
869}
870
871impl Packer for isize {
872    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
873        self.encode(writer)
874    }
875}
876
877impl Decoder for isize {
878    fn decode(reader: &mut Bytes) -> Result<Self> {
879        if reader.remaining() == 0 {
880            return Err(EncoderError::InsufficientData);
881        }
882        if usize::BITS == u64::BITS {
883            Ok(i64::decode(reader)? as isize)
884        } else if usize::BITS == u32::BITS {
885            Ok(i32::decode(reader)? as isize)
886        } else if usize::BITS == u16::BITS {
887            Ok(i16::decode(reader)? as isize)
888        } else {
889            Ok(i128::decode(reader)? as isize)
890        }
891    }
892}
893
894impl Unpacker for isize {
895    fn unpack(reader: &mut Bytes) -> Result<Self> {
896        Self::decode(reader)
897    }
898}
899
900// --- char ---
901/// Encodes a `char` as its Unicode code point using the same format as `u32`.
902impl Encoder for char {
903    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
904        let code_point = *self as u32;
905        code_point.encode(writer)
906    }
907
908    fn is_default(&self) -> bool {
909        *self == '\0'
910    }
911}
912
913impl Packer for char {
914    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
915        self.encode(writer)
916    }
917}
918
919/// Decodes a `char` from its Unicode code point.
920///
921/// # Errors
922/// Returns an error if the code point is not a valid Unicode scalar value.
923impl Decoder for char {
924    fn decode(reader: &mut Bytes) -> Result<Self> {
925        let code_point = u32::decode(reader)?;
926        char::from_u32(code_point).ok_or_else(|| {
927            EncoderError::Decode(format!("Invalid Unicode code point: {}", code_point))
928        })
929    }
930}
931
932impl Unpacker for char {
933    fn unpack(reader: &mut Bytes) -> Result<Self> {
934        Self::decode(reader)
935    }
936}
937
938// --- f32/f64 ---
939/// Encodes an `f32` as a tag and 4 bytes (little-endian IEEE 754).
940impl Encoder for f32 {
941    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
942        writer.put_u8(TAG_F32);
943        writer.put_f32_le(*self);
944        Ok(())
945    }
946
947    fn is_default(&self) -> bool {
948        *self == 0.0
949    }
950}
951
952impl Packer for f32 {
953    /// Packs an `f32` as 4 bytes (little-endian IEEE 754) without a type tag.
954    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
955        if *self == 0.0 {
956            writer.put_u8(TAG_NONE);
957        } else {
958            writer.put_u8(TAG_F32);
959            writer.put_f32_le(*self);
960        }
961        Ok(())
962    }
963}
964
965/// Decodes an `f32` from either 4 or 8 bytes (accepts f64 for compatibility with precision loss).
966impl Decoder for f32 {
967    fn decode(reader: &mut Bytes) -> Result<Self> {
968        if reader.remaining() == 0 {
969            return Err(EncoderError::InsufficientData);
970        }
971        let tag = reader.get_u8();
972        if tag == TAG_F32 {
973            if reader.remaining() < 4 {
974                return Err(EncoderError::InsufficientData);
975            }
976            let mut bytes = [0u8; 4];
977            reader.copy_to_slice(&mut bytes);
978            Ok(f32::from_le_bytes(bytes))
979        } else if tag == TAG_F64 {
980            if reader.remaining() < 8 {
981                return Err(EncoderError::InsufficientData);
982            }
983            let mut bytes = [0u8; 8];
984            reader.copy_to_slice(&mut bytes);
985            Ok(f64::from_le_bytes(bytes) as f32)
986        } else {
987            Err(EncoderError::Decode(format!(
988                "Expected f32/f64 tag ({} or {}), got {}",
989                TAG_F32, TAG_F64, tag
990            )))
991        }
992    }
993}
994
995impl Unpacker for f32 {
996    /// Unpacks an `f32` from either TAG_NONE (0.0) or TAG_F32 + 4 bytes (little-endian IEEE 754).
997    fn unpack(reader: &mut Bytes) -> Result<Self> {
998        if reader.remaining() == 0 {
999            return Err(EncoderError::InsufficientData);
1000        }
1001        let tag = reader.get_u8();
1002        if tag == TAG_NONE {
1003            Ok(0.0)
1004        } else if tag == TAG_F32 {
1005            if reader.remaining() < 4 {
1006                return Err(EncoderError::InsufficientData);
1007            }
1008            let mut bytes = [0u8; 4];
1009            reader.copy_to_slice(&mut bytes);
1010            Ok(f32::from_le_bytes(bytes))
1011        } else {
1012            Err(EncoderError::Decode(format!(
1013                "Expected f32 tag ({} or {}), got {}",
1014                TAG_NONE, TAG_F32, tag
1015            )))
1016        }
1017    }
1018}
1019
1020/// Encodes an `f64` as a tag and 8 bytes (little-endian IEEE 754).
1021impl Encoder for f64 {
1022    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1023        writer.put_u8(TAG_F64);
1024        writer.put_f64_le(*self);
1025        Ok(())
1026    }
1027
1028    fn is_default(&self) -> bool {
1029        *self == 0.0
1030    }
1031}
1032
1033impl Packer for f64 {
1034    /// Packs an `f64` as TAG_NONE (for 0.0) or TAG_F64 + 8 bytes (little-endian IEEE 754).
1035    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1036        if *self == 0.0 {
1037            writer.put_u8(TAG_NONE);
1038        } else {
1039            writer.put_u8(TAG_F64);
1040            writer.put_f64_le(*self);
1041        }
1042        Ok(())
1043    }
1044}
1045
1046/// Decodes an `f64` from 8 bytes (f32 cross-decoding not supported).
1047impl Decoder for f64 {
1048    fn decode(reader: &mut Bytes) -> Result<Self> {
1049        if reader.remaining() == 0 {
1050            return Err(EncoderError::InsufficientData);
1051        }
1052        let tag = reader.get_u8();
1053        if tag == TAG_F64 {
1054            if reader.remaining() < 8 {
1055                return Err(EncoderError::InsufficientData);
1056            }
1057            let mut bytes = [0u8; 8];
1058            reader.copy_to_slice(&mut bytes);
1059            Ok(f64::from_le_bytes(bytes))
1060        } else {
1061            Err(EncoderError::Decode(format!(
1062                "Expected f64 tag ({}), got {}. f32 to f64 cross-decoding is not supported due to precision concerns.",
1063                TAG_F64, tag
1064            )))
1065        }
1066    }
1067}
1068
1069impl Unpacker for f64 {
1070    /// Unpacks an `f64` from either TAG_NONE (0.0) or TAG_F64 + 8 bytes (little-endian IEEE 754).
1071    fn unpack(reader: &mut Bytes) -> Result<Self> {
1072        if reader.remaining() == 0 {
1073            return Err(EncoderError::InsufficientData);
1074        }
1075        let tag = reader.get_u8();
1076        if tag == TAG_NONE {
1077            Ok(0.0)
1078        } else if tag == TAG_F64 {
1079            if reader.remaining() < 8 {
1080                return Err(EncoderError::InsufficientData);
1081            }
1082            let mut bytes = [0u8; 8];
1083            reader.copy_to_slice(&mut bytes);
1084            Ok(f64::from_le_bytes(bytes))
1085        } else {
1086            Err(EncoderError::Decode(format!(
1087                "Expected f64 tag ({} or {}), got {}",
1088                TAG_NONE, TAG_F64, tag
1089            )))
1090        }
1091    }
1092}
1093
1094// --- String ---
1095/// Encodes a `String` as UTF-8 with a length prefix (short strings use a single tag byte).
1096impl Encoder for String {
1097    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1098        let len = self.len();
1099        let max_short = (TAG_STRING_LONG - TAG_STRING_BASE - 1) as usize;
1100        if len <= max_short {
1101            let tag = TAG_STRING_BASE + len as u8; // 9..=29
1102            writer.put_u8(tag);
1103            writer.put_slice(self.as_bytes());
1104        } else {
1105            writer.put_u8(TAG_STRING_LONG);
1106            len.encode(writer)?;
1107            writer.put_slice(self.as_bytes());
1108        }
1109        Ok(())
1110    }
1111
1112    fn is_default(&self) -> bool {
1113        self.is_empty()
1114    }
1115}
1116
1117impl Packer for String {
1118    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1119        self.encode(writer)
1120    }
1121}
1122
1123/// Decodes a `String` from the senax binary format.
1124impl Decoder for String {
1125    fn decode(reader: &mut Bytes) -> Result<Self> {
1126        if reader.remaining() == 0 {
1127            return Err(EncoderError::InsufficientData);
1128        }
1129        let tag = reader.get_u8();
1130        let len = if (TAG_STRING_BASE..TAG_STRING_LONG).contains(&tag) {
1131            (tag - TAG_STRING_BASE) as usize
1132        } else if tag == TAG_STRING_LONG {
1133            usize::decode(reader)?
1134        } else {
1135            return Err(EncoderError::Decode(format!(
1136                "Expected String tag ({}..={}), got {}",
1137                TAG_STRING_BASE, TAG_STRING_LONG, tag
1138            )));
1139        };
1140        if reader.remaining() < len {
1141            return Err(EncoderError::InsufficientData);
1142        }
1143        let mut bytes = vec![0u8; len];
1144        if len > 0 {
1145            reader.copy_to_slice(&mut bytes);
1146        }
1147        String::from_utf8(bytes).map_err(|e| EncoderError::Decode(e.to_string()))
1148    }
1149}
1150
1151impl Unpacker for String {
1152    fn unpack(reader: &mut Bytes) -> Result<Self> {
1153        Self::decode(reader)
1154    }
1155}
1156
1157// --- Option ---
1158/// Encodes an `Option<T>` as a tag byte followed by the value if present.
1159impl<T: Encoder> Encoder for Option<T> {
1160    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1161        match self {
1162            Some(value) => {
1163                writer.put_u8(TAG_SOME);
1164                value.encode(writer)
1165            }
1166            None => {
1167                writer.put_u8(TAG_NONE);
1168                Ok(())
1169            }
1170        }
1171    }
1172
1173    fn is_default(&self) -> bool {
1174        self.is_none()
1175    }
1176}
1177
1178impl<T: Packer> Packer for Option<T> {
1179    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1180        match self {
1181            Some(value) => {
1182                writer.put_u8(TAG_SOME);
1183                value.pack(writer)
1184            }
1185            None => {
1186                writer.put_u8(TAG_NONE);
1187                Ok(())
1188            }
1189        }
1190    }
1191}
1192
1193/// Decodes an `Option<T>` from the senax binary format.
1194impl<T: Decoder> Decoder for Option<T> {
1195    fn decode(reader: &mut Bytes) -> Result<Self> {
1196        if reader.remaining() == 0 {
1197            return Err(EncoderError::InsufficientData); // Not even a tag
1198        }
1199        let tag = reader.get_u8();
1200        match tag {
1201            TAG_NONE => Ok(None),
1202            TAG_SOME => Ok(Some(T::decode(reader)?)),
1203            other => Err(EncoderError::Decode(format!(
1204                "Expected Option tag ({} or {}), got {}",
1205                TAG_NONE, TAG_SOME, other
1206            ))),
1207        }
1208    }
1209}
1210
1211impl<T: Unpacker> Unpacker for Option<T> {
1212    fn unpack(reader: &mut Bytes) -> Result<Self> {
1213        if reader.remaining() == 0 {
1214            return Err(EncoderError::InsufficientData); // Not even a tag
1215        }
1216        let tag = reader.get_u8();
1217        match tag {
1218            TAG_NONE => Ok(None),
1219            TAG_SOME => Ok(Some(T::unpack(reader)?)),
1220            other => Err(EncoderError::Decode(format!(
1221                "Expected Option tag ({} or {}), got {}",
1222                TAG_NONE, TAG_SOME, other
1223            ))),
1224        }
1225    }
1226}
1227
1228// --- Vec<T> ---
1229/// Encodes a `Vec<T>` as a length-prefixed sequence.
1230impl<T: Encoder + 'static> Encoder for Vec<T> {
1231    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1232        encode_vec_length(self.len(), writer)?;
1233        for item in self {
1234            item.encode(writer)?;
1235        }
1236        Ok(())
1237    }
1238
1239    fn is_default(&self) -> bool {
1240        self.is_empty()
1241    }
1242}
1243
1244impl<T: Packer + 'static> Packer for Vec<T> {
1245    /// Packs a `Vec<T>` as a length-prefixed sequence.
1246    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1247        encode_vec_length(self.len(), writer)?;
1248        for item in self {
1249            item.pack(writer)?;
1250        }
1251        Ok(())
1252    }
1253}
1254
1255/// Decodes a `Vec<T>` from the senax binary format.
1256impl<T: Decoder + 'static> Decoder for Vec<T> {
1257    fn decode(reader: &mut Bytes) -> Result<Self> {
1258        let len = decode_vec_length(reader)?;
1259        let mut vec = Vec::with_capacity(len);
1260        for _ in 0..len {
1261            vec.push(T::decode(reader)?);
1262        }
1263        Ok(vec)
1264    }
1265}
1266
1267impl<T: Unpacker + 'static> Unpacker for Vec<T> {
1268    /// Unpacks a `Vec<T>` from the compact format.
1269    fn unpack(reader: &mut Bytes) -> Result<Self> {
1270        let len = decode_vec_length(reader)?;
1271        let mut vec = Vec::with_capacity(len);
1272        for _ in 0..len {
1273            vec.push(T::unpack(reader)?);
1274        }
1275        Ok(vec)
1276    }
1277}
1278
1279// --- Array ---
1280/// Encodes a fixed-size array as a length-prefixed sequence.
1281impl<T: Encoder, const N: usize> Encoder for [T; N] {
1282    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1283        encode_vec_length(N, writer)?;
1284        for item in self {
1285            item.encode(writer)?;
1286        }
1287        Ok(())
1288    }
1289
1290    fn is_default(&self) -> bool {
1291        self.iter().all(|item| item.is_default())
1292    }
1293}
1294
1295impl<T: Packer, const N: usize> Packer for [T; N] {
1296    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1297        encode_vec_length(N, writer)?;
1298        for item in self {
1299            item.pack(writer)?;
1300        }
1301        Ok(())
1302    }
1303}
1304
1305/// Decodes a fixed-size array from the senax binary format.
1306impl<T: Decoder, const N: usize> Decoder for [T; N] {
1307    fn decode(reader: &mut Bytes) -> Result<Self> {
1308        let len = decode_vec_length(reader)?;
1309        if len != N {
1310            return Err(EncoderError::Decode(format!(
1311                "Array length mismatch: expected {}, got {}",
1312                N, len
1313            )));
1314        }
1315        let mut array = Vec::with_capacity(N);
1316        for _ in 0..N {
1317            array.push(T::decode(reader)?);
1318        }
1319        array
1320            .try_into()
1321            .map_err(|_| EncoderError::Decode("Failed to convert Vec to array".to_string()))
1322    }
1323}
1324
1325impl<T: Unpacker, const N: usize> Unpacker for [T; N] {
1326    fn unpack(reader: &mut Bytes) -> Result<Self> {
1327        let len = decode_vec_length(reader)?;
1328        if len != N {
1329            return Err(EncoderError::Decode(format!(
1330                "Array length mismatch: expected {}, got {}",
1331                N, len
1332            )));
1333        }
1334        let mut array = Vec::with_capacity(N);
1335        for _ in 0..N {
1336            array.push(T::unpack(reader)?);
1337        }
1338        array
1339            .try_into()
1340            .map_err(|_| EncoderError::Decode("Failed to convert Vec to array".to_string()))
1341    }
1342}
1343
1344// --- Tuple ---
1345/// Implements encoding/decoding for tuples up to 10 elements.
1346///
1347/// Each tuple is encoded as a length-prefixed sequence of its elements.
1348macro_rules! impl_tuple {
1349    () => {
1350        impl Encoder for () {
1351
1352            fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1353                writer.put_u8(TAG_TUPLE);
1354                0usize.encode(writer)?;
1355                Ok(())
1356            }
1357
1358
1359            fn is_default(&self) -> bool {
1360                true
1361            }
1362        }
1363
1364        impl Packer for () {
1365
1366            fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1367                writer.put_u8(TAG_TUPLE);
1368                0usize.pack(writer)?;
1369                Ok(())
1370            }
1371        }
1372
1373        impl Decoder for () {
1374
1375            fn decode(reader: &mut Bytes) -> Result<Self> {
1376                if reader.remaining() == 0 {
1377                    return Err(EncoderError::InsufficientData);
1378                }
1379                let tag = reader.get_u8();
1380                if tag != TAG_TUPLE {
1381                    return Err(EncoderError::Decode(format!("Expected Tuple tag ({}), got {}", TAG_TUPLE, tag)));
1382                }
1383                let len = usize::decode(reader)?;
1384                if len != 0 {
1385                    return Err(EncoderError::Decode(format!("Expected 0-tuple but got {}-tuple", len)));
1386                }
1387                Ok(())
1388            }
1389        }
1390
1391        impl Unpacker for () {
1392
1393            fn unpack(reader: &mut Bytes) -> Result<Self> {
1394                if reader.remaining() == 0 {
1395                    return Err(EncoderError::InsufficientData);
1396                }
1397                let tag = reader.get_u8();
1398                if tag != TAG_TUPLE {
1399                    return Err(EncoderError::Decode(format!("Expected Tuple tag ({}), got {}", TAG_TUPLE, tag)));
1400                }
1401                let len = usize::decode(reader)?;
1402                if len != 0 {
1403                    return Err(EncoderError::Decode(format!("Expected 0-tuple but got {}-tuple", len)));
1404                }
1405                Ok(())
1406            }
1407        }
1408    };
1409    ($($T:ident: $idx:tt),+) => {
1410        impl<$($T: Encoder),+> Encoder for ($($T,)+) {
1411
1412            fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1413                writer.put_u8(TAG_TUPLE);
1414                let len = count_args!($($T),+);
1415                len.encode(writer)?;
1416                $(
1417                    self.$idx.encode(writer)?;
1418                )+
1419                Ok(())
1420            }
1421
1422
1423            fn is_default(&self) -> bool {
1424                $(self.$idx.is_default())&&+
1425            }
1426        }
1427
1428        impl<$($T: Packer),+> Packer for ($($T,)+) {
1429
1430            fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1431                writer.put_u8(TAG_TUPLE);
1432                let len = count_args!($($T),+);
1433                len.encode(writer)?;
1434                $(
1435                    self.$idx.pack(writer)?;
1436                )+
1437                Ok(())
1438            }
1439        }
1440
1441        impl<$($T: Decoder),+> Decoder for ($($T,)+) {
1442
1443            fn decode(reader: &mut Bytes) -> Result<Self> {
1444                if reader.remaining() == 0 {
1445                    return Err(EncoderError::InsufficientData);
1446                }
1447                let tag = reader.get_u8();
1448                if tag != TAG_TUPLE {
1449                    return Err(EncoderError::Decode(format!("Expected Tuple tag ({}), got {}", TAG_TUPLE, tag)));
1450                }
1451                let len = usize::decode(reader)?;
1452                let expected_len = count_args!($($T),+);
1453                if len != expected_len {
1454                    return Err(EncoderError::Decode(format!("Expected {}-tuple but got {}-tuple", expected_len, len)));
1455                }
1456                Ok(($(
1457                    $T::decode(reader)?,
1458                )+))
1459            }
1460        }
1461
1462        impl<$($T: Unpacker),+> Unpacker for ($($T,)+) {
1463
1464            fn unpack(reader: &mut Bytes) -> Result<Self> {
1465                if reader.remaining() == 0 {
1466                    return Err(EncoderError::InsufficientData);
1467                }
1468                let tag = reader.get_u8();
1469                if tag != TAG_TUPLE {
1470                    return Err(EncoderError::Decode(format!("Expected Tuple tag ({}), got {}", TAG_TUPLE, tag)));
1471                }
1472                let len = usize::decode(reader)?;
1473                let expected_len = count_args!($($T),+);
1474                if len != expected_len {
1475                    return Err(EncoderError::Decode(format!("Expected {}-tuple but got {}-tuple", expected_len, len)));
1476                }
1477                Ok(($(
1478                    $T::unpack(reader)?,
1479                )+))
1480            }
1481        }
1482    };
1483}
1484
1485macro_rules! count_args {
1486    () => { 0 };
1487    ($head:ident $(, $tail:ident)*) => { 1 + count_args!($($tail),*) };
1488}
1489
1490// Generate tuple implementations for 0 to 12 elements
1491impl_tuple!();
1492impl_tuple!(T0: 0);
1493impl_tuple!(T0: 0, T1: 1);
1494impl_tuple!(T0: 0, T1: 1, T2: 2);
1495impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3);
1496impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4);
1497impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5);
1498impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6);
1499impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7);
1500impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8);
1501impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8, T9: 9);
1502impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8, T9: 9, T10: 10);
1503impl_tuple!(T0: 0, T1: 1, T2: 2, T3: 3, T4: 4, T5: 5, T6: 6, T7: 7, T8: 8, T9: 9, T10: 10, T11: 11);
1504
1505// --- Map (HashMap) ---
1506/// Encodes a map as a length-prefixed sequence of key-value pairs.
1507impl<K: Encoder, V: Encoder> Encoder for HashMap<K, V> {
1508    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1509        writer.put_u8(TAG_MAP);
1510        let len = self.len();
1511        len.encode(writer)?;
1512        for (k, v) in self {
1513            k.encode(writer)?;
1514            v.encode(writer)?;
1515        }
1516        Ok(())
1517    }
1518
1519    fn is_default(&self) -> bool {
1520        self.is_empty()
1521    }
1522}
1523
1524impl<K: Packer, V: Packer> Packer for HashMap<K, V> {
1525    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1526        writer.put_u8(TAG_MAP);
1527        let len = self.len();
1528        len.encode(writer)?;
1529        for (k, v) in self {
1530            k.pack(writer)?;
1531            v.pack(writer)?;
1532        }
1533        Ok(())
1534    }
1535}
1536
1537/// Decodes a map from the senax binary format.
1538impl<K: Decoder + Eq + std::hash::Hash, V: Decoder> Decoder for HashMap<K, V> {
1539    fn decode(reader: &mut Bytes) -> Result<Self> {
1540        let len = read_map_header(reader)?;
1541        let mut map = HashMap::with_capacity(len);
1542        for _ in 0..len {
1543            let k = K::decode(reader)?;
1544            let v = V::decode(reader)?;
1545            map.insert(k, v);
1546        }
1547        Ok(map)
1548    }
1549}
1550
1551impl<K: Unpacker + Eq + std::hash::Hash, V: Unpacker> Unpacker for HashMap<K, V> {
1552    fn unpack(reader: &mut Bytes) -> Result<Self> {
1553        let len = read_map_header(reader)?;
1554        let mut map = HashMap::with_capacity(len);
1555        for _ in 0..len {
1556            let k = K::unpack(reader)?;
1557            let v = V::unpack(reader)?;
1558            map.insert(k, v);
1559        }
1560        Ok(map)
1561    }
1562}
1563
1564/// Writes a `u32` in little-endian format without a tag.
1565///
1566/// This is used internally for struct/enum field/variant IDs.
1567pub fn write_u32_le(writer: &mut BytesMut, value: u32) -> Result<()> {
1568    writer.put_u32_le(value);
1569    Ok(())
1570}
1571
1572/// Reads a `u32` in little-endian format without a tag.
1573///
1574/// This is used internally for struct/enum field/variant IDs.
1575pub fn read_u32_le(reader: &mut Bytes) -> Result<u32> {
1576    if reader.remaining() < 4 {
1577        return Err(EncoderError::InsufficientData);
1578    }
1579    Ok(reader.get_u32_le())
1580}
1581
1582/// Writes a `u64` in little-endian format without a tag.
1583///
1584/// This is used internally for struct/enum field/variant IDs.
1585pub fn write_u64_le(writer: &mut BytesMut, value: u64) -> Result<()> {
1586    writer.put_u64_le(value);
1587    Ok(())
1588}
1589
1590/// Reads a `u64` in little-endian format without a tag.
1591///
1592/// This is used internally for struct/enum field/variant IDs.
1593pub fn read_u64_le(reader: &mut Bytes) -> Result<u64> {
1594    if reader.remaining() < 8 {
1595        return Err(EncoderError::InsufficientData);
1596    }
1597    Ok(reader.get_u64_le())
1598}
1599
1600/// Skips a value of any type in the senax binary format.
1601///
1602/// This is used for forward/backward compatibility when unknown fields/variants are encountered.
1603///
1604/// # Errors
1605/// Returns an error if the value cannot be skipped (e.g., insufficient data).
1606pub fn skip_value(reader: &mut Bytes) -> Result<()> {
1607    if reader.remaining() == 0 {
1608        return Err(EncoderError::InsufficientData);
1609    }
1610    let tag = reader.get_u8();
1611    match tag {
1612        TAG_ZERO..=TAG_U8_127 => Ok(()),
1613        TAG_U8 => {
1614            if reader.remaining() == 0 {
1615                return Err(EncoderError::InsufficientData);
1616            }
1617            reader.advance(1);
1618            Ok(())
1619        }
1620        TAG_U16 => {
1621            if reader.remaining() < 2 {
1622                return Err(EncoderError::InsufficientData);
1623            }
1624            reader.advance(2);
1625            Ok(())
1626        }
1627        TAG_U32 => {
1628            if reader.remaining() < 4 {
1629                return Err(EncoderError::InsufficientData);
1630            }
1631            reader.advance(4);
1632            Ok(())
1633        }
1634        TAG_U64 => {
1635            if reader.remaining() < 8 {
1636                return Err(EncoderError::InsufficientData);
1637            }
1638            reader.advance(8);
1639            Ok(())
1640        }
1641        TAG_U128 => {
1642            if reader.remaining() < 16 {
1643                return Err(EncoderError::InsufficientData);
1644            }
1645            reader.advance(16);
1646            Ok(())
1647        }
1648        TAG_F32 => {
1649            if reader.remaining() < 4 {
1650                return Err(EncoderError::InsufficientData);
1651            }
1652            reader.advance(4);
1653            Ok(())
1654        }
1655        TAG_F64 => {
1656            if reader.remaining() < 8 {
1657                return Err(EncoderError::InsufficientData);
1658            }
1659            reader.advance(8);
1660            Ok(())
1661        }
1662        TAG_STRING_BASE..=TAG_STRING_LONG => {
1663            let len = if tag < TAG_STRING_LONG {
1664                (tag - TAG_STRING_BASE) as usize
1665            } else {
1666                usize::decode(reader)?
1667            };
1668            if reader.remaining() < len {
1669                return Err(EncoderError::InsufficientData);
1670            }
1671            reader.advance(len);
1672            Ok(())
1673        }
1674        TAG_BINARY => {
1675            let len = usize::decode(reader)?;
1676            if reader.remaining() < len {
1677                return Err(EncoderError::InsufficientData);
1678            }
1679            reader.advance(len);
1680            Ok(())
1681        }
1682        TAG_ARRAY_VEC_SET_BASE..=TAG_ARRAY_VEC_SET_LONG => {
1683            let len = if tag < TAG_ARRAY_VEC_SET_LONG {
1684                (tag - TAG_ARRAY_VEC_SET_BASE) as usize
1685            } else {
1686                usize::decode(reader)?
1687            };
1688            for _ in 0..len {
1689                skip_value(reader)?;
1690            }
1691            Ok(())
1692        }
1693        TAG_STRUCT_UNIT => Ok(()),
1694        TAG_STRUCT_NAMED => {
1695            loop {
1696                let field_id = read_field_id_optimized(reader)?;
1697                if field_id == 0 {
1698                    break;
1699                }
1700                skip_value(reader)?;
1701            }
1702            Ok(())
1703        }
1704        TAG_STRUCT_UNNAMED => {
1705            let field_count = usize::decode(reader)?;
1706            for _ in 0..field_count {
1707                skip_value(reader)?;
1708            }
1709            Ok(())
1710        }
1711        TAG_ENUM => {
1712            let _variant_id = read_field_id_optimized(reader)?;
1713            Ok(())
1714        }
1715        TAG_ENUM_NAMED => {
1716            let _variant_id = read_field_id_optimized(reader)?;
1717            loop {
1718                let field_id = read_field_id_optimized(reader)?;
1719                if field_id == 0 {
1720                    break;
1721                }
1722                skip_value(reader)?;
1723            }
1724            Ok(())
1725        }
1726        TAG_ENUM_UNNAMED => {
1727            let _variant_id = read_field_id_optimized(reader)?;
1728            let field_count = usize::decode(reader)?;
1729            for _ in 0..field_count {
1730                skip_value(reader)?;
1731            }
1732            Ok(())
1733        }
1734        TAG_TUPLE => {
1735            let len = usize::decode(reader)?;
1736            for _ in 0..len {
1737                skip_value(reader)?;
1738            }
1739            Ok(())
1740        }
1741        TAG_MAP => {
1742            let len = usize::decode(reader)?;
1743            for _ in 0..len {
1744                skip_value(reader)?; // key
1745                skip_value(reader)?; // value
1746            }
1747            Ok(())
1748        }
1749        TAG_CHRONO_DATETIME => {
1750            if reader.remaining() < 12 {
1751                return Err(EncoderError::InsufficientData);
1752            } // Approximation for i64 + u32, could be more precise
1753            let _timestamp_seconds = i64::decode(reader)?;
1754            let _timestamp_nanos = u32::decode(reader)?;
1755            Ok(())
1756        }
1757        TAG_CHRONO_NAIVE_DATE => {
1758            if reader.remaining() < 8 {
1759                return Err(EncoderError::InsufficientData);
1760            } // Approximation for i64
1761            let _days_from_epoch = i64::decode(reader)?;
1762            Ok(())
1763        }
1764        TAG_CHRONO_NAIVE_TIME => {
1765            if reader.remaining() < 8 {
1766                return Err(EncoderError::InsufficientData);
1767            } // Approximation for u32 + u32
1768            let _seconds_from_midnight = u32::decode(reader)?;
1769            let _nanoseconds = u32::decode(reader)?;
1770            Ok(())
1771        }
1772        TAG_CHRONO_NAIVE_DATETIME => {
1773            if reader.remaining() < 12 {
1774                return Err(EncoderError::InsufficientData);
1775            } // Approximation for i64 + u32
1776            let _timestamp_seconds = i64::decode(reader)?;
1777            let _timestamp_nanos = u32::decode(reader)?;
1778            Ok(())
1779        }
1780        TAG_DECIMAL => {
1781            if reader.remaining() < 20 {
1782                return Err(EncoderError::InsufficientData);
1783            } // Approximation for i128 + u32
1784            let _mantissa = i128::decode(reader)?;
1785            let _scale = u32::decode(reader)?;
1786            Ok(())
1787        }
1788        TAG_UUID => {
1789            // Covers ULID as well
1790            if reader.remaining() < 16 {
1791                return Err(EncoderError::InsufficientData);
1792            }
1793            reader.advance(16);
1794            Ok(())
1795        }
1796        TAG_JSON_NULL => Ok(()),
1797        TAG_JSON_BOOL => Ok(()),
1798        TAG_JSON_NUMBER => {
1799            // Number has type marker + actual number
1800            if reader.remaining() == 0 {
1801                return Err(EncoderError::InsufficientData);
1802            }
1803            let number_type = reader.get_u8();
1804            match number_type {
1805                0 => {
1806                    u64::decode(reader)?;
1807                }
1808                1 => {
1809                    i64::decode(reader)?;
1810                }
1811                2 => {
1812                    f64::decode(reader)?;
1813                }
1814                _ => {
1815                    return Err(EncoderError::Decode(format!(
1816                        "Invalid JSON Number type marker: {}",
1817                        number_type
1818                    )));
1819                }
1820            }
1821            Ok(())
1822        }
1823        TAG_JSON_STRING => {
1824            // String uses regular string encoding
1825            String::decode(reader)?;
1826            Ok(())
1827        }
1828        TAG_JSON_ARRAY => {
1829            let len = usize::decode(reader)?;
1830            for _ in 0..len {
1831                skip_value(reader)?;
1832            }
1833            Ok(())
1834        }
1835        TAG_JSON_OBJECT => {
1836            let len = usize::decode(reader)?;
1837            for _ in 0..len {
1838                String::decode(reader)?; // key
1839                skip_value(reader)?; // value
1840            }
1841            Ok(())
1842        }
1843        TAG_NONE | TAG_SOME => {
1844            // These should have been handled by Option<T> decode or skip_value for T
1845            // For TAG_NONE, it's fine. For TAG_SOME, we need to skip the inner value.
1846            if tag == TAG_SOME {
1847                skip_value(reader)?;
1848            }
1849            Ok(())
1850        }
1851        _ => Err(EncoderError::Decode(format!(
1852            "skip_value: unknown or unhandled tag {}",
1853            tag
1854        ))),
1855    }
1856}
1857
1858// --- HashSet, BTreeSet, IndexSet ---
1859/// Encodes a set as a length-prefixed sequence of elements.
1860impl<T: Encoder + Eq + std::hash::Hash> Encoder for HashSet<T> {
1861    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1862        encode_vec_length(self.len(), writer)?;
1863        for v in self {
1864            v.encode(writer)?;
1865        }
1866        Ok(())
1867    }
1868
1869    fn is_default(&self) -> bool {
1870        self.is_empty()
1871    }
1872}
1873
1874impl<T: Packer + Eq + std::hash::Hash> Packer for HashSet<T> {
1875    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1876        encode_vec_length(self.len(), writer)?;
1877        for v in self {
1878            v.pack(writer)?;
1879        }
1880        Ok(())
1881    }
1882}
1883
1884/// Decodes a set from the senax binary format.
1885impl<T: Decoder + Eq + std::hash::Hash + 'static> Decoder for HashSet<T> {
1886    fn decode(reader: &mut Bytes) -> Result<Self> {
1887        let vec: Vec<T> = Vec::decode(reader)?;
1888        Ok(vec.into_iter().collect())
1889    }
1890}
1891
1892impl<T: Unpacker + Eq + std::hash::Hash + 'static> Unpacker for HashSet<T> {
1893    fn unpack(reader: &mut Bytes) -> Result<Self> {
1894        let vec: Vec<T> = Vec::unpack(reader)?;
1895        Ok(vec.into_iter().collect())
1896    }
1897}
1898// --- BTreeSet ---
1899impl<T: Encoder + Ord> Encoder for BTreeSet<T> {
1900    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1901        encode_vec_length(self.len(), writer)?;
1902        for v in self {
1903            v.encode(writer)?;
1904        }
1905        Ok(())
1906    }
1907
1908    fn is_default(&self) -> bool {
1909        self.is_empty()
1910    }
1911}
1912
1913impl<T: Packer + Ord> Packer for BTreeSet<T> {
1914    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1915        encode_vec_length(self.len(), writer)?;
1916        for v in self {
1917            v.pack(writer)?;
1918        }
1919        Ok(())
1920    }
1921}
1922
1923impl<T: Decoder + Ord + 'static> Decoder for BTreeSet<T> {
1924    fn decode(reader: &mut Bytes) -> Result<Self> {
1925        let vec: Vec<T> = Vec::decode(reader)?;
1926        Ok(vec.into_iter().collect())
1927    }
1928}
1929
1930impl<T: Unpacker + Ord + 'static> Unpacker for BTreeSet<T> {
1931    fn unpack(reader: &mut Bytes) -> Result<Self> {
1932        let vec: Vec<T> = Vec::unpack(reader)?;
1933        Ok(vec.into_iter().collect())
1934    }
1935}
1936// --- BTreeMap ---
1937impl<K: Encoder + Ord, V: Encoder> Encoder for BTreeMap<K, V> {
1938    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1939        writer.put_u8(TAG_MAP);
1940        let len = self.len();
1941        len.encode(writer)?;
1942        for (k, v) in self {
1943            k.encode(writer)?;
1944            v.encode(writer)?;
1945        }
1946        Ok(())
1947    }
1948
1949    fn is_default(&self) -> bool {
1950        self.is_empty()
1951    }
1952}
1953
1954impl<K: Packer + Ord, V: Packer> Packer for BTreeMap<K, V> {
1955    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
1956        writer.put_u8(TAG_MAP);
1957        let len = self.len();
1958        len.encode(writer)?;
1959        for (k, v) in self {
1960            k.pack(writer)?;
1961            v.pack(writer)?;
1962        }
1963        Ok(())
1964    }
1965}
1966
1967impl<K: Decoder + Ord, V: Decoder> Decoder for BTreeMap<K, V> {
1968    fn decode(reader: &mut Bytes) -> Result<Self> {
1969        let len = read_map_header(reader)?;
1970        let mut map = BTreeMap::new();
1971        for _ in 0..len {
1972            let k = K::decode(reader)?;
1973            let v = V::decode(reader)?;
1974            map.insert(k, v);
1975        }
1976        Ok(map)
1977    }
1978}
1979
1980impl<K: Unpacker + Ord, V: Unpacker> Unpacker for BTreeMap<K, V> {
1981    fn unpack(reader: &mut Bytes) -> Result<Self> {
1982        let len = read_map_header(reader)?;
1983        let mut map = BTreeMap::new();
1984        for _ in 0..len {
1985            let k = K::unpack(reader)?;
1986            let v = V::unpack(reader)?;
1987            map.insert(k, v);
1988        }
1989        Ok(map)
1990    }
1991}
1992
1993// --- Bytes ---
1994impl Encoder for Bytes {
1995    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
1996        writer.put_u8(TAG_BINARY);
1997        let len = self.len();
1998        len.encode(writer)?;
1999        writer.put_slice(self);
2000        Ok(())
2001    }
2002
2003    fn is_default(&self) -> bool {
2004        self.is_empty()
2005    }
2006}
2007
2008impl Packer for Bytes {
2009    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
2010        writer.put_u8(TAG_BINARY);
2011        let len = self.len();
2012        len.encode(writer)?;
2013        writer.put_slice(self);
2014        Ok(())
2015    }
2016}
2017
2018impl Decoder for Bytes {
2019    fn decode(reader: &mut Bytes) -> Result<Self> {
2020        if reader.remaining() == 0 {
2021            return Err(EncoderError::InsufficientData);
2022        }
2023        let tag = reader.get_u8();
2024        let len = if tag == TAG_BINARY {
2025            usize::decode(reader)?
2026        } else if (TAG_STRING_BASE..TAG_STRING_LONG).contains(&tag) {
2027            (tag - TAG_STRING_BASE) as usize
2028        } else if tag == TAG_STRING_LONG {
2029            usize::decode(reader)?
2030        } else {
2031            return Err(EncoderError::Decode(format!(
2032                "Expected Bytes tag ({} or {}..={}), got {}",
2033                TAG_BINARY, TAG_STRING_BASE, TAG_STRING_LONG, tag
2034            )));
2035        };
2036
2037        if reader.remaining() < len {
2038            return Err(EncoderError::InsufficientData);
2039        }
2040
2041        Ok(reader.split_to(len))
2042    }
2043}
2044
2045impl Unpacker for Bytes {
2046    fn unpack(reader: &mut Bytes) -> Result<Self> {
2047        if reader.remaining() == 0 {
2048            return Err(EncoderError::InsufficientData);
2049        }
2050        let tag = reader.get_u8();
2051        let len = if tag == TAG_BINARY {
2052            usize::unpack(reader)?
2053        } else if (TAG_STRING_BASE..TAG_STRING_LONG).contains(&tag) {
2054            (tag - TAG_STRING_BASE) as usize
2055        } else if tag == TAG_STRING_LONG {
2056            usize::unpack(reader)?
2057        } else {
2058            return Err(EncoderError::Decode(format!(
2059                "Expected Bytes tag ({} or {}..={}), got {}",
2060                TAG_BINARY, TAG_STRING_BASE, TAG_STRING_LONG, tag
2061            )));
2062        };
2063
2064        if reader.remaining() < len {
2065            return Err(EncoderError::InsufficientData);
2066        }
2067
2068        Ok(reader.split_to(len))
2069    }
2070}
2071
2072// --- Arc<T> ---
2073/// Encodes an `Arc<T>` by encoding the inner value.
2074impl<T: Encoder> Encoder for Arc<T> {
2075    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
2076        (**self).encode(writer)
2077    }
2078
2079    fn is_default(&self) -> bool {
2080        T::is_default(self)
2081    }
2082}
2083
2084impl<T: Packer> Packer for Arc<T> {
2085    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
2086        (**self).pack(writer)
2087    }
2088}
2089
2090/// Decodes an `Arc<T>` by decoding the inner value and wrapping it in an Arc.
2091impl<T: Decoder> Decoder for Arc<T> {
2092    fn decode(reader: &mut Bytes) -> Result<Self> {
2093        Ok(Arc::new(T::decode(reader)?))
2094    }
2095}
2096
2097impl<T: Unpacker> Unpacker for Arc<T> {
2098    fn unpack(reader: &mut Bytes) -> Result<Self> {
2099        Ok(Arc::new(T::unpack(reader)?))
2100    }
2101}
2102
2103/// Writes a `u64` in little-endian format without a tag.
2104///
2105/// This is used internally for struct/enum field/variant IDs.
2106pub fn write_field_id_optimized(writer: &mut BytesMut, field_id: u64) -> Result<()> {
2107    if field_id == 0 {
2108        // Terminator
2109        writer.put_u8(0);
2110    } else if (1..=250).contains(&field_id) {
2111        // Small field ID: write as u8
2112        writer.put_u8(field_id as u8);
2113    } else {
2114        // Large field ID: write 255 marker then u64
2115        writer.put_u8(255);
2116        writer.put_u64_le(field_id);
2117    }
2118    Ok(())
2119}
2120
2121/// Reads a field ID using optimized encoding.
2122///
2123/// Returns Ok(0) for terminator, Ok(field_id) for valid field ID.
2124pub fn read_field_id_optimized(reader: &mut Bytes) -> Result<u64> {
2125    if reader.remaining() == 0 {
2126        return Err(EncoderError::InsufficientData);
2127    }
2128
2129    let first_byte = reader.get_u8();
2130
2131    if first_byte == 0 {
2132        // Terminator
2133        Ok(0)
2134    } else if first_byte == 255 {
2135        // Large field ID follows
2136        if reader.remaining() < 8 {
2137            return Err(EncoderError::InsufficientData);
2138        }
2139        Ok(reader.get_u64_le())
2140    } else {
2141        // Small field ID
2142        Ok(first_byte as u64)
2143    }
2144}
2145
2146/// Implementation for references - delegates to the referenced value
2147impl<T: Encoder> Encoder for &T {
2148    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
2149        (*self).encode(writer)
2150    }
2151
2152    fn is_default(&self) -> bool {
2153        (*self).is_default()
2154    }
2155}
2156
2157impl<T: Packer> Packer for &T {
2158    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
2159        (*self).pack(writer)
2160    }
2161}
2162
2163// --- Box<T> ---
2164/// Encodes a `Box<T>` by encoding the inner value.
2165impl<T: Encoder> Encoder for Box<T> {
2166    fn encode(&self, writer: &mut BytesMut) -> Result<()> {
2167        (**self).encode(writer)
2168    }
2169
2170    fn is_default(&self) -> bool {
2171        T::is_default(self)
2172    }
2173}
2174
2175impl<T: Packer> Packer for Box<T> {
2176    fn pack(&self, writer: &mut BytesMut) -> Result<()> {
2177        (**self).pack(writer)
2178    }
2179}
2180
2181/// Decodes a `Box<T>` by decoding the inner value and wrapping it in a Box.
2182impl<T: Decoder> Decoder for Box<T> {
2183    fn decode(reader: &mut Bytes) -> Result<Self> {
2184        Ok(Box::new(T::decode(reader)?))
2185    }
2186}
2187
2188impl<T: Unpacker> Unpacker for Box<T> {
2189    fn unpack(reader: &mut Bytes) -> Result<Self> {
2190        Ok(Box::new(T::unpack(reader)?))
2191    }
2192}
2193
2194/// Encodes the length for array/vec/set format.
2195#[inline(never)]
2196pub(crate) fn encode_vec_length(len: usize, writer: &mut BytesMut) -> Result<()> {
2197    let max_short = (TAG_ARRAY_VEC_SET_LONG - TAG_ARRAY_VEC_SET_BASE - 1) as usize;
2198    if len <= max_short {
2199        let tag = TAG_ARRAY_VEC_SET_BASE + len as u8;
2200        writer.put_u8(tag);
2201    } else {
2202        writer.put_u8(TAG_ARRAY_VEC_SET_LONG);
2203        len.encode(writer)?;
2204    }
2205    Ok(())
2206}
2207
2208/// Decodes the length for array/vec/set format.
2209#[inline(never)]
2210pub(crate) fn decode_vec_length(reader: &mut Bytes) -> Result<usize> {
2211    if reader.remaining() == 0 {
2212        return Err(EncoderError::InsufficientData);
2213    }
2214    let tag = reader.get_u8();
2215    if (TAG_ARRAY_VEC_SET_BASE..TAG_ARRAY_VEC_SET_LONG).contains(&tag) {
2216        Ok((tag - TAG_ARRAY_VEC_SET_BASE) as usize)
2217    } else if tag == TAG_ARRAY_VEC_SET_LONG {
2218        usize::decode(reader)
2219    } else {
2220        Err(EncoderError::Decode(format!(
2221            "Expected Vec tag ({}..={}), got {}",
2222            TAG_ARRAY_VEC_SET_BASE, TAG_ARRAY_VEC_SET_LONG, tag
2223        )))
2224    }
2225}
2226
2227/// Reads and validates TAG_MAP, then returns the map length.
2228///
2229/// This helper function is used by all map-like types (HashMap, BTreeMap, etc.)
2230/// to avoid code duplication in decode/unpack implementations.
2231#[inline(never)]
2232pub(crate) fn read_map_header(reader: &mut Bytes) -> Result<usize> {
2233    if reader.remaining() == 0 {
2234        return Err(EncoderError::InsufficientData);
2235    }
2236    let tag = reader.get_u8();
2237    if tag != TAG_MAP {
2238        return Err(EncoderError::Decode(format!(
2239            "Expected Map tag ({}), got {}",
2240            TAG_MAP, tag
2241        )));
2242    }
2243    usize::decode(reader)
2244}