//! Decoding: reading protocol values from a byte stream. use crate::context::Context; use std::{io::Read, sync::Arc}; use crate::{DEFAULT_BUFFER_LEN, codec::error::Result}; macro_rules! impl_decode { ($type: ty) => { impl Decode for $type { // decode number using big endian fn decode(reader: &mut dyn Read, _: &Context) -> Result where Self: Sized, { const BYTES: usize = (<$type>::BITS / 8) as usize; let mut bytes = [0; BYTES]; reader.read_exact(&mut bytes)?; Ok(<$type>::from_be_bytes(bytes)) } } }; } /// Read a value from a byte stream pub trait Decode { fn decode(reader: &mut dyn Read, ctx: &Context) -> Result where Self: Sized; } impl Decode for bool { fn decode(reader: &mut dyn Read, _: &Context) -> Result where Self: Sized, { let mut byte = [0_u8]; reader.read_exact(&mut byte)?; Ok(byte[0] != 0) } } impl> Decode for Option { fn decode(reader: &mut dyn Read, ctx: &Context) -> Result where Self: Sized, { let tag = u8::decode(reader, ctx)?; if tag == 0 { Ok(None) } else { Ok(Some(T::decode(reader, ctx)?)) } } } impl> Decode for Vec { fn decode(reader: &mut dyn Read, ctx: &Context) -> Result where Self: Sized, { let len = usize::decode(reader, ctx)?; let mut vec = Vec::with_capacity(len); for _ in 0..len { vec.push(T::decode(reader, ctx)?); } Ok(vec) } } impl Decode for String { fn decode(reader: &mut dyn Read, _: &Context) -> Result where Self: Sized, { let mut bytes: Vec = Vec::new(); reader.read_to_end(&mut bytes)?; Ok(String::from_utf8_lossy(&bytes).to_string()) } } impl Decode for Arc<[u8]> { fn decode(reader: &mut dyn Read, _: &Context) -> Result { let mut buf = Vec::with_capacity(DEFAULT_BUFFER_LEN); reader.read_to_end(&mut buf)?; Ok(Arc::<[u8]>::from(buf.into_boxed_slice())) } } impl Decode for [u8; S] { fn decode(reader: &mut dyn Read, _: &Context) -> Result where Self: Sized, { let mut slice = [0_u8; S]; reader.read_exact(&mut slice)?; Ok(slice) } } 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(reader: &mut dyn Read, ctx: &Context) -> Result where Self: Sized, { let bits = u64::decode(reader, ctx)?; let value = f64::from_bits(bits); Ok(value) } } impl Decode for f32 { fn decode(reader: &mut dyn Read, ctx: &Context) -> Result where Self: Sized, { let bits = u32::decode(reader, ctx)?; let value = f32::from_bits(bits); Ok(value) } }