Skip to main content

asun/
binary.rs

1//! ASUN Binary Format (ASUN-BIN)
2//!
3//! A high-performance binary encoding for ASUN data structures.
4//! Provides `encode_binary` and `decode_binary` for zero-overhead struct ↔ bytes conversion.
5//!
6//! ## Wire Format (all integers little-endian)
7//!
8//! ```text
9//! bool      → 1 byte  (0x00=false, 0x01=true)
10//! i8        → 1 byte (signed)
11//! i16       → 2 bytes LE
12//! i32       → 4 bytes LE
13//! i64       → 8 bytes LE
14//! u8        → 1 byte
15//! u16       → 2 bytes LE
16//! u32       → 4 bytes LE
17//! u64       → 8 bytes LE
18//! f32       → 4 bytes LE (IEEE 754 bit-cast)
19//! f64       → 8 bytes LE (IEEE 754 bit-cast)
20//! char      → 4 bytes LE (Unicode scalar as u32)
21//! str       → u32 LE length + UTF-8 bytes  ← ZERO-COPY on decode (&'de str)
22//! bytes     → u32 LE length + raw bytes
23//! Option<T> → u8 tag (0=None, 1=Some) + [T payload if Some]
24//! Vec<T>    → u32 LE count + [element × count]
25//! struct    → fields in declaration order (no length prefix — known from schema)
26//! tuple     → elements in order (no length prefix)
27//! enum      → u32 LE variant_index + [payload for non-unit variants]
28//! unit      → 0 bytes
29//! newtype   → inner value directly (no wrapper)
30//! ```
31//!
32//! ## Key Features
33//!
34//! - **Zero-copy string decode**: borrowed `&'de str` slices directly reference input bytes.
35//! - **No type tags** for struct fields: schema drives layout (like Protobuf binary, not CBOR).
36//! - **SIMD-accelerated** bulk byte copy for large string payloads (≥ 32 bytes).
37//! - All primitives written/read via `to_le_bytes` / `from_le_bytes` — compiler typically
38//!   emits a single `STR`/`LDR` instruction on aarch64 / `MOV`/`MOV` on x86-64.
39
40use crate::error::{Error, Result};
41use crate::simd;
42use core::mem;
43use serde::de::{self, DeserializeSeed, EnumAccess, SeqAccess, VariantAccess, Visitor};
44use serde::ser::{
45    self, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
46    SerializeTupleStruct, SerializeTupleVariant,
47};
48use serde::{Deserialize, Serialize};
49
50// ============================================================================
51// Public API
52// ============================================================================
53
54/// Encode `value` to a `Vec<u8>` using the ASUN binary format.
55///
56/// # Example
57/// ```rust,ignore
58/// let user = User { id: 1, name: "Alice".into(), active: true };
59/// let bytes = asun::encode_binary(&user)?;
60/// ```
61#[inline]
62pub fn encode_binary<T: Serialize>(value: &T) -> Result<Vec<u8>> {
63    let mut ser = BinaryEncoder::with_capacity(256);
64    value.serialize(&mut ser)?;
65    Ok(ser.buf)
66}
67
68/// Decode a value from ASUN binary bytes.
69///
70/// The lifetime `'de` allows **zero-copy** decoding: any `&'de str` fields
71/// in the target type will borrow directly from `data` with no allocation.
72///
73/// # Example
74/// ```rust,ignore
75/// let user: User = asun::decode_binary(&bytes)?;
76/// ```
77#[inline]
78pub fn decode_binary<'de, T: Deserialize<'de>>(data: &'de [u8]) -> Result<T> {
79    let mut de = BinaryDecoder::new(data);
80    let v = T::deserialize(&mut de)?;
81    Ok(v)
82}
83
84// ============================================================================
85// BinaryEncoder
86// ============================================================================
87
88pub struct BinaryEncoder {
89    pub(crate) buf: Vec<u8>,
90}
91
92impl BinaryEncoder {
93    #[inline]
94    pub fn new() -> Self {
95        Self { buf: Vec::new() }
96    }
97
98    #[inline]
99    pub fn with_capacity(cap: usize) -> Self {
100        Self {
101            buf: Vec::with_capacity(cap),
102        }
103    }
104
105    // ------------------------------------------------------------------
106    // Primitive writers — each emits fixed bytes, zero heap allocation
107    // ------------------------------------------------------------------
108
109    #[inline(always)]
110    fn write_u8(&mut self, v: u8) {
111        self.buf.push(v);
112    }
113
114    #[inline(always)]
115    fn write_u16(&mut self, v: u16) {
116        self.buf.extend_from_slice(&v.to_le_bytes());
117    }
118
119    #[inline(always)]
120    fn write_u32(&mut self, v: u32) {
121        self.buf.extend_from_slice(&v.to_le_bytes());
122    }
123
124    #[inline(always)]
125    fn write_u64(&mut self, v: u64) {
126        self.buf.extend_from_slice(&v.to_le_bytes());
127    }
128
129    #[inline(always)]
130    fn write_i8(&mut self, v: i8) {
131        self.buf.push(v as u8);
132    }
133
134    #[inline(always)]
135    fn write_i16(&mut self, v: i16) {
136        self.buf.extend_from_slice(&v.to_le_bytes());
137    }
138
139    #[inline(always)]
140    fn write_i32(&mut self, v: i32) {
141        self.buf.extend_from_slice(&v.to_le_bytes());
142    }
143
144    #[inline(always)]
145    fn write_i64(&mut self, v: i64) {
146        self.buf.extend_from_slice(&v.to_le_bytes());
147    }
148
149    #[inline(always)]
150    fn write_f32(&mut self, v: f32) {
151        // Bit-cast: no conversion, just copy 4 IEEE-754 bytes
152        self.buf.extend_from_slice(&v.to_bits().to_le_bytes());
153    }
154
155    #[inline(always)]
156    fn write_f64(&mut self, v: f64) {
157        // Bit-cast: no conversion, just copy 8 IEEE-754 bytes
158        self.buf.extend_from_slice(&v.to_bits().to_le_bytes());
159    }
160
161    /// Write raw bytes with SIMD bulk copy for large payloads.
162    #[inline]
163    fn write_bytes_raw(&mut self, data: &[u8]) {
164        simd::simd_bulk_extend(&mut self.buf, data);
165    }
166
167    /// Write a string: `u32 LE length` + UTF-8 bytes.
168    #[inline]
169    fn write_str(&mut self, s: &str) {
170        let bytes = s.as_bytes();
171        self.write_u32(bytes.len() as u32);
172        self.write_bytes_raw(bytes);
173    }
174}
175
176// ============================================================================
177// serde::Serializer impl
178// ============================================================================
179
180impl<'a> ser::Serializer for &'a mut BinaryEncoder {
181    type Ok = ();
182    type Error = Error;
183
184    type SerializeSeq = BinSeqEnc<'a>;
185    type SerializeTuple = &'a mut BinaryEncoder;
186    type SerializeTupleStruct = &'a mut BinaryEncoder;
187    type SerializeTupleVariant = &'a mut BinaryEncoder;
188    type SerializeMap = ser::Impossible<(), Error>;
189    type SerializeStruct = &'a mut BinaryEncoder;
190    type SerializeStructVariant = &'a mut BinaryEncoder;
191
192    #[inline]
193    fn serialize_bool(self, v: bool) -> Result<()> {
194        self.write_u8(v as u8);
195        Ok(())
196    }
197
198    #[inline]
199    fn serialize_i8(self, v: i8) -> Result<()> {
200        self.write_i8(v);
201        Ok(())
202    }
203
204    #[inline]
205    fn serialize_i16(self, v: i16) -> Result<()> {
206        self.write_i16(v);
207        Ok(())
208    }
209
210    #[inline]
211    fn serialize_i32(self, v: i32) -> Result<()> {
212        self.write_i32(v);
213        Ok(())
214    }
215
216    #[inline]
217    fn serialize_i64(self, v: i64) -> Result<()> {
218        self.write_i64(v);
219        Ok(())
220    }
221
222    #[inline]
223    fn serialize_u8(self, v: u8) -> Result<()> {
224        self.write_u8(v);
225        Ok(())
226    }
227
228    #[inline]
229    fn serialize_u16(self, v: u16) -> Result<()> {
230        self.write_u16(v);
231        Ok(())
232    }
233
234    #[inline]
235    fn serialize_u32(self, v: u32) -> Result<()> {
236        self.write_u32(v);
237        Ok(())
238    }
239
240    #[inline]
241    fn serialize_u64(self, v: u64) -> Result<()> {
242        self.write_u64(v);
243        Ok(())
244    }
245
246    #[inline]
247    fn serialize_f32(self, v: f32) -> Result<()> {
248        self.write_f32(v);
249        Ok(())
250    }
251
252    #[inline]
253    fn serialize_f64(self, v: f64) -> Result<()> {
254        self.write_f64(v);
255        Ok(())
256    }
257
258    #[inline]
259    fn serialize_char(self, v: char) -> Result<()> {
260        self.write_u32(v as u32);
261        Ok(())
262    }
263
264    #[inline]
265    fn serialize_str(self, v: &str) -> Result<()> {
266        self.write_str(v);
267        Ok(())
268    }
269
270    #[inline]
271    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
272        self.write_u32(v.len() as u32);
273        self.write_bytes_raw(v);
274        Ok(())
275    }
276
277    #[inline]
278    fn serialize_none(self) -> Result<()> {
279        self.write_u8(0);
280        Ok(())
281    }
282
283    #[inline]
284    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
285        self.write_u8(1);
286        value.serialize(self)
287    }
288
289    /// Unit / unit struct / unit variant → 0 bytes.
290    #[inline]
291    fn serialize_unit(self) -> Result<()> {
292        Ok(())
293    }
294
295    #[inline]
296    fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
297        Ok(())
298    }
299
300    #[inline]
301    fn serialize_unit_variant(
302        self,
303        _name: &'static str,
304        variant_index: u32,
305        _variant: &'static str,
306    ) -> Result<()> {
307        self.write_u32(variant_index);
308        Ok(())
309    }
310
311    #[inline]
312    fn serialize_newtype_struct<T: ?Sized + Serialize>(
313        self,
314        _name: &'static str,
315        value: &T,
316    ) -> Result<()> {
317        value.serialize(self)
318    }
319
320    #[inline]
321    fn serialize_newtype_variant<T: ?Sized + Serialize>(
322        self,
323        _name: &'static str,
324        variant_index: u32,
325        _variant: &'static str,
326        value: &T,
327    ) -> Result<()> {
328        self.write_u32(variant_index);
329        value.serialize(self)
330    }
331
332    /// Sequence: write placeholder u32 count (fixed up in `end()`).
333    fn serialize_seq(self, len: Option<usize>) -> Result<BinSeqEnc<'a>> {
334        Ok(BinSeqEnc::new(self, len))
335    }
336
337    /// Tuple: known length, no prefix needed.
338    fn serialize_tuple(self, _len: usize) -> Result<&'a mut BinaryEncoder> {
339        Ok(self)
340    }
341
342    fn serialize_tuple_struct(
343        self,
344        _name: &'static str,
345        _len: usize,
346    ) -> Result<&'a mut BinaryEncoder> {
347        Ok(self)
348    }
349
350    fn serialize_tuple_variant(
351        self,
352        _name: &'static str,
353        variant_index: u32,
354        _variant: &'static str,
355        _len: usize,
356    ) -> Result<&'a mut BinaryEncoder> {
357        self.write_u32(variant_index);
358        Ok(self)
359    }
360
361    fn serialize_map(self, _len: Option<usize>) -> Result<ser::Impossible<(), Error>> {
362        Err(Error::Message("map fields are not supported".into()))
363    }
364
365    /// Struct: fields written in order, no length prefix.
366    fn serialize_struct(
367        self,
368        _name: &'static str,
369        _len: usize,
370    ) -> Result<&'a mut BinaryEncoder> {
371        Ok(self)
372    }
373
374    fn serialize_struct_variant(
375        self,
376        _name: &'static str,
377        variant_index: u32,
378        _variant: &'static str,
379        _len: usize,
380    ) -> Result<&'a mut BinaryEncoder> {
381        self.write_u32(variant_index);
382        Ok(self)
383    }
384
385    fn is_human_readable(&self) -> bool {
386        false
387    }
388}
389
390// ============================================================================
391// BinSeqEnc — handles sequences with unknown-at-call-time lengths
392// ============================================================================
393
394pub struct BinSeqEnc<'a> {
395    enc: &'a mut BinaryEncoder,
396    /// Byte position in `buf` where the `u32` count placeholder lives.
397    len_pos: usize,
398    count: u32,
399}
400
401impl<'a> BinSeqEnc<'a> {
402    fn new(enc: &'a mut BinaryEncoder, known_len: Option<usize>) -> Self {
403        let len_pos = enc.buf.len();
404        // Write placeholder — will be fixed up in end()
405        let count = known_len.unwrap_or(0) as u32;
406        enc.write_u32(count);
407        BinSeqEnc {
408            enc,
409            len_pos,
410            count: 0,
411        }
412    }
413
414    #[inline(always)]
415    fn fix_len(&mut self) {
416        let bytes = self.count.to_le_bytes();
417        self.enc.buf[self.len_pos..self.len_pos + 4].copy_from_slice(&bytes);
418    }
419}
420
421impl<'a> SerializeSeq for BinSeqEnc<'a> {
422    type Ok = ();
423    type Error = Error;
424
425    #[inline]
426    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
427        self.count += 1;
428        value.serialize(&mut *self.enc)
429    }
430
431    #[inline]
432    fn end(mut self) -> Result<()> {
433        self.fix_len();
434        Ok(())
435    }
436}
437
438impl<'a> SerializeTupleVariant for &'a mut BinaryEncoder {
439    type Ok = ();
440    type Error = Error;
441
442    #[inline]
443    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
444        value.serialize(&mut **self)
445    }
446
447    #[inline]
448    fn end(self) -> Result<()> {
449        Ok(())
450    }
451}
452
453// ============================================================================
454// Tuple / Struct — use &mut BinaryEncoder directly (no count prefix)
455// ============================================================================
456
457impl<'a> SerializeTuple for &'a mut BinaryEncoder {
458    type Ok = ();
459    type Error = Error;
460
461    #[inline]
462    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
463        value.serialize(&mut **self)
464    }
465
466    #[inline]
467    fn end(self) -> Result<()> {
468        Ok(())
469    }
470}
471
472impl<'a> SerializeTupleStruct for &'a mut BinaryEncoder {
473    type Ok = ();
474    type Error = Error;
475
476    #[inline]
477    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
478        value.serialize(&mut **self)
479    }
480
481    #[inline]
482    fn end(self) -> Result<()> {
483        Ok(())
484    }
485}
486
487impl<'a> SerializeStruct for &'a mut BinaryEncoder {
488    type Ok = ();
489    type Error = Error;
490
491    #[inline]
492    fn serialize_field<T: ?Sized + Serialize>(
493        &mut self,
494        _key: &'static str,
495        value: &T,
496    ) -> Result<()> {
497        value.serialize(&mut **self)
498    }
499
500    #[inline]
501    fn end(self) -> Result<()> {
502        Ok(())
503    }
504}
505
506impl<'a> SerializeStructVariant for &'a mut BinaryEncoder {
507    type Ok = ();
508    type Error = Error;
509
510    #[inline]
511    fn serialize_field<T: ?Sized + Serialize>(
512        &mut self,
513        _key: &'static str,
514        value: &T,
515    ) -> Result<()> {
516        value.serialize(&mut **self)
517    }
518
519    #[inline]
520    fn end(self) -> Result<()> {
521        Ok(())
522    }
523}
524
525// ============================================================================
526// BinaryDecoder
527// ============================================================================
528
529pub struct BinaryDecoder<'de> {
530    data: &'de [u8],
531    pos: usize,
532}
533
534impl<'de> BinaryDecoder<'de> {
535    #[inline]
536    pub fn new(data: &'de [u8]) -> Self {
537        Self { data, pos: 0 }
538    }
539
540    // ------------------------------------------------------------------
541    // Primitive readers — all inline, zero allocation
542    // ------------------------------------------------------------------
543
544    #[inline(always)]
545    fn ensure(&self, n: usize) -> Result<()> {
546        if self.pos + n <= self.data.len() {
547            Ok(())
548        } else {
549            Err(Error::Eof)
550        }
551    }
552
553    #[inline(always)]
554    fn read_u8(&mut self) -> Result<u8> {
555        self.ensure(1)?;
556        let v = self.data[self.pos];
557        self.pos += 1;
558        Ok(v)
559    }
560
561    #[inline(always)]
562    fn read_u16(&mut self) -> Result<u16> {
563        self.ensure(2)?;
564        let v = u16::from_le_bytes(self.data[self.pos..self.pos + 2].try_into().unwrap());
565        self.pos += 2;
566        Ok(v)
567    }
568
569    #[inline(always)]
570    fn read_u32(&mut self) -> Result<u32> {
571        self.ensure(4)?;
572        let v = u32::from_le_bytes(self.data[self.pos..self.pos + 4].try_into().unwrap());
573        self.pos += 4;
574        Ok(v)
575    }
576
577    #[inline(always)]
578    fn read_u64(&mut self) -> Result<u64> {
579        self.ensure(8)?;
580        let v = u64::from_le_bytes(self.data[self.pos..self.pos + 8].try_into().unwrap());
581        self.pos += 8;
582        Ok(v)
583    }
584
585    #[inline(always)]
586    fn read_i8(&mut self) -> Result<i8> {
587        Ok(self.read_u8()? as i8)
588    }
589
590    #[inline(always)]
591    fn read_i16(&mut self) -> Result<i16> {
592        self.ensure(2)?;
593        let v = i16::from_le_bytes(self.data[self.pos..self.pos + 2].try_into().unwrap());
594        self.pos += 2;
595        Ok(v)
596    }
597
598    #[inline(always)]
599    fn read_i32(&mut self) -> Result<i32> {
600        self.ensure(4)?;
601        let v = i32::from_le_bytes(self.data[self.pos..self.pos + 4].try_into().unwrap());
602        self.pos += 4;
603        Ok(v)
604    }
605
606    #[inline(always)]
607    fn read_i64(&mut self) -> Result<i64> {
608        self.ensure(8)?;
609        let v = i64::from_le_bytes(self.data[self.pos..self.pos + 8].try_into().unwrap());
610        self.pos += 8;
611        Ok(v)
612    }
613
614    #[inline(always)]
615    fn read_f32(&mut self) -> Result<f32> {
616        // Bit-cast: read 4 bytes, interpret as IEEE-754 float32
617        let bits = self.read_u32()?;
618        Ok(f32::from_bits(bits))
619    }
620
621    #[inline(always)]
622    fn read_f64(&mut self) -> Result<f64> {
623        // Bit-cast: read 8 bytes, interpret as IEEE-754 float64
624        let bits = self.read_u64()?;
625        Ok(f64::from_bits(bits))
626    }
627
628    /// Read string **without allocation** — returns a `&'de str` borrowing `data`.
629    ///
630    /// This is the core zero-copy path: callers with `&'de str` fields pay
631    /// only for the `u32` length read + a bounds check.
632    #[inline]
633    fn read_str_zerocopy(&mut self) -> Result<&'de str> {
634        let len = self.read_u32()? as usize;
635        self.ensure(len)?;
636        let bytes = &self.data[self.pos..self.pos + len];
637        self.pos += len;
638        // SAFETY: serializer always writes valid UTF-8 (from Rust &str/String)
639        Ok(unsafe { core::str::from_utf8_unchecked(bytes) })
640    }
641
642    /// Read raw bytes slice — zero-copy borrow of input.
643    #[inline]
644    fn read_bytes_zerocopy(&mut self) -> Result<&'de [u8]> {
645        let len = self.read_u32()? as usize;
646        self.ensure(len)?;
647        let bytes = &self.data[self.pos..self.pos + len];
648        self.pos += len;
649        Ok(bytes)
650    }
651}
652
653// ============================================================================
654// serde::Deserializer impl
655// ============================================================================
656
657impl<'de, 'a> de::Deserializer<'de> for &'a mut BinaryDecoder<'de> {
658    type Error = Error;
659
660    /// Binary format is NOT self-describing — type tags are absent.
661    /// `deserialize_any` is only called by generic serde code that inspect values.
662    fn deserialize_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
663        Err(Error::Message(
664            "ASUN binary format is not self-describing; use typed deserialization".into(),
665        ))
666    }
667
668    #[inline]
669    fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
670        visitor.visit_bool(self.read_u8()? != 0)
671    }
672
673    #[inline]
674    fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
675        visitor.visit_i8(self.read_i8()?)
676    }
677
678    #[inline]
679    fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
680        visitor.visit_i16(self.read_i16()?)
681    }
682
683    #[inline]
684    fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
685        visitor.visit_i32(self.read_i32()?)
686    }
687
688    #[inline]
689    fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
690        visitor.visit_i64(self.read_i64()?)
691    }
692
693    #[inline]
694    fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
695        visitor.visit_u8(self.read_u8()?)
696    }
697
698    #[inline]
699    fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
700        visitor.visit_u16(self.read_u16()?)
701    }
702
703    #[inline]
704    fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
705        visitor.visit_u32(self.read_u32()?)
706    }
707
708    #[inline]
709    fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
710        visitor.visit_u64(self.read_u64()?)
711    }
712
713    #[inline]
714    fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
715        visitor.visit_f32(self.read_f32()?)
716    }
717
718    #[inline]
719    fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
720        visitor.visit_f64(self.read_f64()?)
721    }
722
723    #[inline]
724    fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
725        let cp = self.read_u32()?;
726        let c = char::from_u32(cp)
727            .ok_or_else(|| Error::Message(format!("invalid char codepoint: {cp}")))?;
728        visitor.visit_char(c)
729    }
730
731    /// Zero-copy: returns `&'de str` borrowing directly from `data`.
732    #[inline]
733    fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
734        let s = self.read_str_zerocopy()?;
735        visitor.visit_borrowed_str(s)
736    }
737
738    /// For `String` fields: still zero-copy for the borrow; serde calls `visit_borrowed_str`
739    /// and converts to `String` if needed. No intermediate `String::new()` call here.
740    #[inline]
741    fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
742        let s = self.read_str_zerocopy()?;
743        visitor.visit_borrowed_str(s)
744    }
745
746    #[inline]
747    fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
748        let bytes = self.read_bytes_zerocopy()?;
749        visitor.visit_borrowed_bytes(bytes)
750    }
751
752    #[inline]
753    fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
754        let bytes = self.read_bytes_zerocopy()?;
755        visitor.visit_borrowed_bytes(bytes)
756    }
757
758    #[inline]
759    fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
760        let tag = self.read_u8()?;
761        if tag == 0 {
762            visitor.visit_none()
763        } else {
764            visitor.visit_some(self)
765        }
766    }
767
768    #[inline]
769    fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
770        visitor.visit_unit()
771    }
772
773    #[inline]
774    fn deserialize_unit_struct<V: Visitor<'de>>(
775        self,
776        _name: &'static str,
777        visitor: V,
778    ) -> Result<V::Value> {
779        visitor.visit_unit()
780    }
781
782    #[inline]
783    fn deserialize_newtype_struct<V: Visitor<'de>>(
784        self,
785        _name: &'static str,
786        visitor: V,
787    ) -> Result<V::Value> {
788        visitor.visit_newtype_struct(self)
789    }
790
791    /// Sequence: read `u32 LE` count, then deliver elements via `SeqAccess`.
792    fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
793        let count = self.read_u32()? as usize;
794        visitor.visit_seq(BinSeqAccess::new(self, count))
795    }
796
797    /// Tuple: length known from schema, no prefix in data.
798    fn deserialize_tuple<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
799        visitor.visit_seq(BinSeqAccess::new(self, len))
800    }
801
802    fn deserialize_tuple_struct<V: Visitor<'de>>(
803        self,
804        _name: &'static str,
805        len: usize,
806        visitor: V,
807    ) -> Result<V::Value> {
808        visitor.visit_seq(BinSeqAccess::new(self, len))
809    }
810
811    fn deserialize_map<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
812        Err(Error::Message("map fields are not supported".into()))
813    }
814
815    /// Struct: fields are positional — no count prefix in data.
816    /// The field count is supplied by the generated `Deserialize` impl via `fields`.
817    fn deserialize_struct<V: Visitor<'de>>(
818        self,
819        _name: &'static str,
820        fields: &'static [&'static str],
821        visitor: V,
822    ) -> Result<V::Value> {
823        visitor.visit_seq(BinSeqAccess::new(self, fields.len()))
824    }
825
826    fn deserialize_enum<V: Visitor<'de>>(
827        self,
828        _name: &'static str,
829        _variants: &'static [&'static str],
830        visitor: V,
831    ) -> Result<V::Value> {
832        visitor.visit_enum(BinEnumAccess { de: self })
833    }
834
835    /// Identifier: not used in binary (positional), but must be implemented.
836    fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
837        self.deserialize_str(visitor)
838    }
839
840    fn deserialize_ignored_any<V: Visitor<'de>>(self, _visitor: V) -> Result<V::Value> {
841        Err(Error::Message("cannot ignore in binary format".into()))
842    }
843
844    fn is_human_readable(&self) -> bool {
845        false
846    }
847}
848
849// ============================================================================
850// SeqAccess — drives struct and sequence deserialization
851// ============================================================================
852
853struct BinSeqAccess<'a, 'de: 'a> {
854    de: &'a mut BinaryDecoder<'de>,
855    remaining: usize,
856}
857
858impl<'a, 'de> BinSeqAccess<'a, 'de> {
859    #[inline]
860    fn new(de: &'a mut BinaryDecoder<'de>, remaining: usize) -> Self {
861        Self { de, remaining }
862    }
863}
864
865impl<'de, 'a> SeqAccess<'de> for BinSeqAccess<'a, 'de> {
866    type Error = Error;
867
868    #[inline]
869    fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>> {
870        if self.remaining == 0 {
871            return Ok(None);
872        }
873        self.remaining -= 1;
874        seed.deserialize(&mut *self.de).map(Some)
875    }
876
877    #[inline]
878    fn size_hint(&self) -> Option<usize> {
879        Some(self.remaining)
880    }
881}
882
883// ============================================================================
884// EnumAccess + VariantAccess — drives enum deserialization
885// ============================================================================
886
887struct BinEnumAccess<'a, 'de: 'a> {
888    de: &'a mut BinaryDecoder<'de>,
889}
890
891impl<'de, 'a> EnumAccess<'de> for BinEnumAccess<'a, 'de> {
892    type Error = Error;
893    type Variant = BinVariantAccess<'a, 'de>;
894
895    fn variant_seed<V: DeserializeSeed<'de>>(
896        self,
897        seed: V,
898    ) -> Result<(V::Value, BinVariantAccess<'a, 'de>)> {
899        // variant index encoded as u32 LE
900        let idx = self.de.read_u32()?;
901        let val = seed.deserialize(de::value::U32Deserializer::new(idx))?;
902        Ok((val, BinVariantAccess { de: self.de }))
903    }
904}
905
906struct BinVariantAccess<'a, 'de: 'a> {
907    de: &'a mut BinaryDecoder<'de>,
908}
909
910impl<'de, 'a> VariantAccess<'de> for BinVariantAccess<'a, 'de> {
911    type Error = Error;
912
913    fn unit_variant(self) -> Result<()> {
914        Ok(())
915    }
916
917    fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
918        seed.deserialize(self.de)
919    }
920
921    fn tuple_variant<V: Visitor<'de>>(self, len: usize, visitor: V) -> Result<V::Value> {
922        visitor.visit_seq(BinSeqAccess::new(self.de, len))
923    }
924
925    fn struct_variant<V: Visitor<'de>>(
926        self,
927        fields: &'static [&'static str],
928        visitor: V,
929    ) -> Result<V::Value> {
930        visitor.visit_seq(BinSeqAccess::new(self.de, fields.len()))
931    }
932}
933
934// ============================================================================
935// Compile-time size check
936// ============================================================================
937
938const _: () = {
939    // BinaryDecoder: &[u8] (2 usize fat ptr) + usize pos = 3 usize
940    assert!(mem::size_of::<BinaryDecoder<'_>>() == 3 * mem::size_of::<usize>());
941};
942
943#[cfg(test)]
944mod tests {
945    use super::*;
946    use serde::{Deserialize, Serialize};
947
948    #[derive(Debug, Serialize, Deserialize, PartialEq)]
949    struct User {
950        id: i64,
951        name: String,
952        score: f64,
953        active: bool,
954    }
955
956    #[derive(Debug, Serialize, Deserialize, PartialEq)]
957    struct AllPrims {
958        b: bool,
959        i8v: i8,
960        i16v: i16,
961        i32v: i32,
962        i64v: i64,
963        u8v: u8,
964        u16v: u16,
965        u32v: u32,
966        u64v: u64,
967        f32v: f32,
968        f64v: f64,
969    }
970
971    #[derive(Debug, Serialize, Deserialize, PartialEq)]
972    struct WithOption {
973        id: i64,
974        label: Option<String>,
975    }
976
977    #[derive(Debug, Serialize, Deserialize, PartialEq)]
978    struct WithVec {
979        name: String,
980        scores: Vec<i64>,
981    }
982
983    #[test]
984    fn test_user_roundtrip() {
985        let u = User {
986            id: 42,
987            name: "Alice".into(),
988            score: 9.5,
989            active: true,
990        };
991        let bytes = encode_binary(&u).unwrap();
992        let u2: User = decode_binary(&bytes).unwrap();
993        assert_eq!(u, u2);
994    }
995
996    #[test]
997    fn test_all_primitives() {
998        let v = AllPrims {
999            b: true,
1000            i8v: -1,
1001            i16v: -300,
1002            i32v: -70000,
1003            i64v: i64::MIN,
1004            u8v: 255,
1005            u16v: 65535,
1006            u32v: u32::MAX,
1007            u64v: u64::MAX,
1008            f32v: 3.15,
1009            f64v: 2.718281828,
1010        };
1011        let bytes = encode_binary(&v).unwrap();
1012        let v2: AllPrims = decode_binary(&bytes).unwrap();
1013        assert_eq!(v, v2);
1014    }
1015
1016    #[test]
1017    fn test_option_some_none() {
1018        let a = WithOption {
1019            id: 1,
1020            label: Some("hello".into()),
1021        };
1022        let b = WithOption { id: 2, label: None };
1023        let b1 = encode_binary(&a).unwrap();
1024        let b2 = encode_binary(&b).unwrap();
1025        let a2: WithOption = decode_binary(&b1).unwrap();
1026        let b3: WithOption = decode_binary(&b2).unwrap();
1027        assert_eq!(a, a2);
1028        assert_eq!(b, b3);
1029    }
1030
1031    #[test]
1032    fn test_vec_roundtrip() {
1033        let v = WithVec {
1034            name: "stats".into(),
1035            scores: vec![10, 20, 30, 40, 50],
1036        };
1037        let bytes = encode_binary(&v).unwrap();
1038        let v2: WithVec = decode_binary(&bytes).unwrap();
1039        assert_eq!(v, v2);
1040    }
1041
1042    #[test]
1043    fn test_vec_of_structs() {
1044        let users = vec![
1045            User {
1046                id: 1,
1047                name: "Alice".into(),
1048                score: 9.0,
1049                active: true,
1050            },
1051            User {
1052                id: 2,
1053                name: "Bob".into(),
1054                score: 7.5,
1055                active: false,
1056            },
1057        ];
1058        let bytes = encode_binary(&users).unwrap();
1059        let users2: Vec<User> = decode_binary(&bytes).unwrap();
1060        assert_eq!(users, users2);
1061    }
1062
1063    #[test]
1064    fn test_entry_list_roundtrip() {
1065        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1066        struct Entry {
1067            key: String,
1068            value: i64,
1069        }
1070        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1071        struct M {
1072            data: Vec<Entry>,
1073        }
1074        let m = M {
1075            data: vec![
1076                Entry {
1077                    key: "a".into(),
1078                    value: 1,
1079                },
1080                Entry {
1081                    key: "b".into(),
1082                    value: 2,
1083                },
1084            ],
1085        };
1086        let bytes = encode_binary(&m).unwrap();
1087        let m2: M = decode_binary(&bytes).unwrap();
1088        assert_eq!(m, m2);
1089    }
1090
1091    #[test]
1092    fn test_enum_roundtrip() {
1093        #[derive(Debug, Serialize, Deserialize, PartialEq)]
1094        enum Color {
1095            Red,
1096            Green,
1097            Blue,
1098            Custom(u8, u8, u8),
1099        }
1100        for c in [
1101            Color::Red,
1102            Color::Green,
1103            Color::Blue,
1104            Color::Custom(10, 20, 30),
1105        ] {
1106            let bytes = encode_binary(&c).unwrap();
1107            let c2: Color = decode_binary(&bytes).unwrap();
1108            assert_eq!(c, c2);
1109        }
1110    }
1111
1112    #[test]
1113    fn test_binary_size_vs_text() {
1114        let users: Vec<User> = (0..100)
1115            .map(|i| User {
1116                id: i,
1117                name: format!("User_{}", i),
1118                score: i as f64 * 0.5,
1119                active: i % 2 == 0,
1120            })
1121            .collect();
1122        let bin = encode_binary(&users).unwrap();
1123        let json = serde_json::to_string(&users).unwrap();
1124        // Binary should be significantly smaller
1125        assert!(
1126            bin.len() < json.len(),
1127            "bin={} json={}",
1128            bin.len(),
1129            json.len()
1130        );
1131    }
1132}