use crate::codec::error::Result; use crate::context::Context; use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque}; macro_rules! impl_encode { ($t:ty) => { impl Encode for $t { fn encode(&self, buffer: &mut Vec, _: &Context) -> Result { buffer.extend_from_slice(&self.to_be_bytes()); Ok(std::mem::size_of::<$t>()) } fn encode_slice(slice: &[Self], buffer: &mut Vec, _: &Context) -> Result where Self: Sized, { let len = slice.len() * std::mem::size_of::<$t>(); buffer.reserve(len); for item in slice { buffer.extend_from_slice(&item.to_be_bytes()); } Ok(len) } fn encode_iter<'a, I>(iter: I, buffer: &mut Vec, ctx: &Context) -> Result where Self: 'a + Sized, I: IntoIterator, { let mut len = 0; for item in iter { len += item.encode(buffer, ctx)?; } Ok(len) } } }; } macro_rules! impl_encode_tuples { ($($generic: ident),+) => { impl Encode for ($($generic,)+) where $($generic: Encode),+ { #[allow(non_snake_case)] fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let ($($generic,)+): &($($generic,)+) = self; let mut len = 0; $(len += $generic.encode(buffer, ctx)?;)+ Ok(len) } } }; } /// Zero-copy encoding: writes directly into a byte buffer pub trait Encode { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result; fn encode_slice(slice: &[Self], buffer: &mut Vec, ctx: &Context) -> Result where Self: Sized, { let mut len = 0; for item in slice { len += item.encode(buffer, ctx)?; } Ok(len) } fn encode_iter<'a, I>(iter: I, buffer: &mut Vec, ctx: &Context) -> Result where Self: 'a + Sized, I: IntoIterator, { let mut len = 0; for item in iter { len += item.encode(buffer, ctx)?; } Ok(len) } } // ── Encode arrays ─────────────────────────────────────────────────────── impl> Encode for Vec { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self, buffer, ctx) } } impl> Encode for VecDeque { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let (front, back) = self.as_slices(); let mut len = 0; len += T::encode_slice(front, buffer, ctx)?; len += T::encode_slice(back, buffer, ctx)?; Ok(len) } } impl> Encode for LinkedList { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let mut len = 0; for item in self { len += item.encode(buffer, ctx)?; } Ok(len) } } // ── Encode slices ─────────────────────────────────────────────────────── impl> Encode for &[T] { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self, buffer, ctx) } } impl, const S: usize> Encode for [T; S] { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self, buffer, ctx) } } impl> Encode for [T] { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self, buffer, ctx) } } // ── Encode references to collections ──────────────────────────────────── impl> Encode for &Vec { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self, buffer, ctx) } } impl> Encode for &VecDeque { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let (front, back) = self.as_slices(); let mut len = 0; len += T::encode_slice(front, buffer, ctx)?; len += T::encode_slice(back, buffer, ctx)?; Ok(len) } } impl> Encode for &LinkedList { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let mut len = 0; for item in (*self).iter() { len += item.encode(buffer, ctx)?; } Ok(len) } } impl> Encode for &HashSet { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_iter(self.iter(), buffer, ctx) } } impl> Encode for &BTreeSet { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_iter(self.iter(), buffer, ctx) } } impl> Encode for &BinaryHeap { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self.as_slice(), buffer, ctx) } } impl Encode for &HashMap where K: Encode, V: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let mut len = 0; for (k, v) in (*self).iter() { len += k.encode(buffer, ctx)?; len += v.encode(buffer, ctx)?; } Ok(len) } } impl Encode for &BTreeMap where K: Encode, V: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let mut len = 0; for (k, v) in (*self).iter() { len += k.encode(buffer, ctx)?; len += v.encode(buffer, ctx)?; } Ok(len) } } // ── Encode set (owned) ────────────────────────────────────────────────── impl> Encode for HashSet { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_iter(self.iter(), buffer, ctx) } } impl> Encode for BTreeSet { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_iter(self.iter(), buffer, ctx) } } // ── Encode misc ───────────────────────────────────────────────────────── impl Encode for BinaryHeap where T: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { T::encode_slice(self.as_slice(), buffer, ctx) } } // ── Encode maps (owned) ───────────────────────────────────────────────── impl Encode for HashMap where K: Encode, V: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let mut len = 0; for (k, v) in self { len += k.encode(buffer, ctx)?; len += v.encode(buffer, ctx)?; } Ok(len) } } impl Encode for BTreeMap where K: Encode, V: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { let mut len = 0; for (k, v) in self { len += k.encode(buffer, ctx)?; len += v.encode(buffer, ctx)?; } Ok(len) } } // ── Encode string ─────────────────────────────────────────────────────── impl Encode for String { fn encode(&self, buffer: &mut Vec, _: &Context) -> Result { let utf8 = self.as_bytes(); buffer.extend_from_slice(utf8); Ok(utf8.len()) } } impl Encode for &str { fn encode(&self, buffer: &mut Vec, _: &Context) -> Result { let utf8 = self.as_bytes(); buffer.extend_from_slice(utf8); Ok(utf8.len()) } } impl> Encode for Option { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { match self { Some(val) => val.encode(buffer, ctx), None => Ok(0), } } } // ── Encode primitive ──────────────────────────────────────────────────── impl Encode for bool { fn encode(&self, buffer: &mut Vec, _: &Context) -> Result { buffer.push(*self as u8); Ok(1) } fn encode_slice(slice: &[Self], buffer: &mut Vec, _: &Context) -> Result where Self: Sized, { let len = slice.len(); buffer.reserve(len); for &b in slice { buffer.push(b as u8); } Ok(len) } } // ── Encode pointer ────────────────────────────────────────────────────── impl Encode for std::sync::Arc where T: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { self.as_ref().encode(buffer, ctx) } } impl Encode for std::sync::Arc<[T]> where T: Encode, { fn encode(&self, buffer: &mut Vec, ctx: &Context) -> Result { self.as_ref().encode(buffer, ctx) } } impl_encode!(u8); impl_encode!(u16); impl_encode!(u32); impl_encode!(u64); impl_encode!(u128); impl_encode!(usize); impl_encode!(i8); impl_encode!(i16); impl_encode!(i32); impl_encode!(i64); impl_encode!(i128); impl_encode!(isize); #[cfg(feature = "f16")] impl_encode!(f16); impl_encode!(f32); impl_encode!(f64); #[cfg(feature = "f128")] impl_encode!(f128); // ── Encode tuple ──────────────────────────────────────────────────────── impl Encode for () { fn encode(&self, _: &mut Vec, _: &Context) -> Result { Ok(0) } fn encode_slice(_: &[Self], _: &mut Vec, _: &Context) -> Result where Self: Sized, { Ok(0) } } impl_encode_tuples!(A); impl_encode_tuples!(A, B); impl_encode_tuples!(A, B, C); impl_encode_tuples!(A, B, C, D); impl_encode_tuples!(A, B, C, D, E); impl_encode_tuples!(A, B, C, D, E, F); impl_encode_tuples!(A, B, C, D, E, F, G); impl_encode_tuples!(A, B, C, D, E, F, G, H); impl_encode_tuples!(A, B, C, D, E, F, G, H, I); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);