use std::{ collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet}, hash::Hash, sync::Arc, }; use crate::{codec::error::Result, codec::error::CodecError, context::Context}; macro_rules! impl_decode { ($t:ty) => { impl Decode for $t { fn decode(buf: &mut &[u8], _: &Context) -> Result where Self: Sized, { const BYTES: usize = std::mem::size_of::<$t>(); if buf.len() < BYTES { return Err(CodecError::IoError(std::io::Error::new( std::io::ErrorKind::UnexpectedEof, "insufficient bytes", ))); } let (bytes, rest) = buf.split_at(BYTES); *buf = rest; Ok(<$t>::from_be_bytes(bytes.try_into().unwrap())) } fn decode_slice(buf: &mut &[u8], _: &Context) -> Result> where Self: Sized, { const BYTES: usize = std::mem::size_of::<$t>(); let count = buf.len() / BYTES; let mut vec = Vec::with_capacity(count); for _ in 0..count { let (bytes, rest) = buf.split_at(BYTES); *buf = rest; vec.push(<$t>::from_be_bytes(bytes.try_into().unwrap())); } Ok(vec) } } }; } macro_rules! impl_decode_tuples { ($($generic: ident),+) => { impl Decode for ($($generic,)+) where $($generic: Decode),+ { #[allow(non_snake_case)] fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { $( let $generic = $generic::decode(buf, ctx)?; )+ Ok(($($generic,)+)) } } }; } /// Zero-copy decoding: reads directly from a byte slice pub trait Decode { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized; fn decode_slice(buf: &mut &[u8], ctx: &Context) -> Result> where Self: Sized, { let mut vec = Vec::new(); while !buf.is_empty() { match Self::decode(buf, ctx) { Ok(value) => vec.push(value), Err(CodecError::IoError(err)) if err.kind() == std::io::ErrorKind::UnexpectedEof => { return Ok(vec); } Err(err) => return Err(err), } } Ok(vec) } } // ── Decode arrays ─────────────────────────────────────────────────────── impl> Decode for Vec { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(buf, ctx)?; let mut vec = Vec::with_capacity(len); for _ in 0..len { vec.push(T::decode(buf, ctx)?); } Ok(vec) } } impl> Decode for Option { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { if buf.is_empty() { return Ok(None); } T::decode(buf, ctx).map(Some) } } // ── Decode slices ─────────────────────────────────────────────────────── impl Decode for [T; S] where T: Decode + Default + Copy, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let slice = T::decode_slice(buf, ctx)?; let got = slice.len(); slice .as_array() .cloned() .ok_or(CodecError::WrongSize { expected: S, got }) } } impl Decode for &[T] where T: Decode + Default + Copy, { fn decode(_: &mut &[u8], _: &Context) -> Result where Self: Sized, { unimplemented!() } } // ── Decode set ────────────────────────────────────────────────────────── impl Decode for HashSet where T: Decode + Eq + Hash, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(buf, ctx)?; let mut set = HashSet::with_capacity(len); for _ in 0..len { set.insert(T::decode(buf, ctx)?); } Ok(set) } } impl Decode for BTreeSet where T: Decode + Ord, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(buf, ctx)?; let mut set = BTreeSet::new(); for _ in 0..len { set.insert(T::decode(buf, ctx)?); } Ok(set) } } // ── Decode misc ───────────────────────────────────────────────────────── impl Decode for BinaryHeap where T: Decode + Ord, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(buf, ctx)?; let mut heap = BinaryHeap::with_capacity(len); for _ in 0..len { heap.push(T::decode(buf, ctx)?); } Ok(heap) } } // ── Decode maps ───────────────────────────────────────────────────────── impl Decode for HashMap where K: Decode + Eq + Hash, V: Decode, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(buf, ctx)?; let mut map = HashMap::with_capacity(len); for _ in 0..len { let key = K::decode(buf, ctx)?; let val = V::decode(buf, ctx)?; map.insert(key, val); } Ok(map) } } impl Decode for BTreeMap where K: Decode + Ord, V: Decode, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(buf, ctx)?; let mut map = BTreeMap::new(); for _ in 0..len { let key = K::decode(buf, ctx)?; let val = V::decode(buf, ctx)?; map.insert(key, val); } Ok(map) } } // ── Decode string - requires length prefix ────────────────────────────── impl Decode for &str { fn decode(_: &mut &[u8], _: &Context) -> Result where Self: Sized, { unimplemented!() } } impl Decode for String { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { // String must be length-prefixed - decode as LenPrefixed crate::types::prefix::length::LenPrefixed::::decode(buf, ctx) .map(|p| p.data().clone()) } } // ── Decode primitive ──────────────────────────────────────────────────── impl_decode!(u8); impl_decode!(u16); impl_decode!(u32); impl_decode!(u64); impl_decode!(u128); impl_decode!(usize); impl_decode!(i8); impl_decode!(i16); impl_decode!(i32); impl_decode!(i64); impl_decode!(i128); impl_decode!(isize); impl Decode for f64 { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let bits = u64::decode(buf, ctx)?; Ok(f64::from_bits(bits)) } } impl Decode for f32 { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let bits = u32::decode(buf, ctx)?; Ok(f32::from_bits(bits)) } } impl Decode for bool { fn decode(buf: &mut &[u8], _: &Context) -> Result where Self: Sized, { if buf.is_empty() { return Err(CodecError::IoError(std::io::Error::new( std::io::ErrorKind::UnexpectedEof, "insufficient bytes for bool", ))); } let b = buf[0]; *buf = &buf[1..]; Ok(b != 0) } } // ── Decode tuple ──────────────────────────────────────────────────────── impl_decode_tuples!(A); impl_decode_tuples!(A, B); impl_decode_tuples!(A, B, C); impl_decode_tuples!(A, B, C, D); impl_decode_tuples!(A, B, C, D, E); impl_decode_tuples!(A, B, C, D, E, F); impl_decode_tuples!(A, B, C, D, E, F, G); impl_decode_tuples!(A, B, C, D, E, F, G, H); impl_decode_tuples!(A, B, C, D, E, F, G, H, I); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); impl_decode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q); // ── Decode pointer ────────────────────────────────────────────────────── impl Decode for std::sync::Arc where T: Decode, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result { T::decode(buf, ctx).map(Arc::new) } } impl Decode for Arc<[T]> where T: Decode, { fn decode(buf: &mut &[u8], ctx: &Context) -> Result where Self: Sized, { let slice = T::decode_slice(buf, ctx)?; Ok(slice.into()) } }