//! Encoding: writing protocol values into a byte stream. use crate::codec::error::Error; use std::{io::Write, sync::Arc}; macro_rules! impl_encode { ($t: ty) => { impl Encode for $t { /// write number using big endian fn encode(&self, buffer: &mut dyn Write, _: &mut Ctx) -> Result { let size = buffer.write(&self.to_be_bytes())?; Ok(size) } } }; } /// Write a value into a byte stream pub trait Encode { fn encode(&self, buffer: &mut dyn Write, ctx: &mut Ctx) -> Result; } impl Encode for bool { fn encode(&self, buffer: &mut dyn Write, _: &mut Ctx) -> Result { let size = buffer.write(&[*self as u8])?; Ok(size) } } impl> Encode for Option { /// Encode `T` if Some(T) or do nothing if None fn encode(&self, buffer: &mut dyn Write, ctx: &mut Ctx) -> Result { match self { Some(val) => { let size = val.encode(buffer, ctx)?; Ok(size) } None => Ok(0), } } } impl> Encode for Vec { /// Encode each element of vector /// use `CountPrefix` to prefix the vector with number of elements /// use `LenPrefix` to prefix the vector with encoded byte size fn encode(&self, buffer: &mut dyn Write, ctx: &mut Ctx) -> Result { let mut size = 0; for item in self { size += item.encode(buffer, ctx)?; } Ok(size) } } impl Encode for String { /// Encode the string using utf8 /// use `CountPrefix` to prefix the string with char length /// use `LenPrefix` to prefix the string with utf8 bytes length fn encode(&self, buffer: &mut dyn Write, _: &mut Ctx) -> Result { let utf8 = self.as_bytes(); buffer.write_all(utf8)?; Ok(utf8.len()) } } impl Encode for Arc<[u8]> { /// write raw slice into the buffer /// use `LenPrefix` to prefix with byte length fn encode(&self, buffer: &mut dyn Write, _: &mut Ctx) -> Result { let len = buffer.write(self)?; Ok(len) } } impl Encode for [u8; S] { /// write raw slice into the buffer /// use `LenPrefix` to prefix with byte length fn encode(&self, buffer: &mut dyn Write, _ctx: &mut Ctx) -> Result { let len = buffer.write(self)?; Ok(len) } } 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); impl_encode!(f32); impl_encode!(f64);