#[cfg(test)]
mod tests;
use crate::error::Error;
use crate::put_bytes::PutBytes;
pub trait ToBytes {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error>;
}
impl ToBytes for bool {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
let val = if *self { 1u8 } else { 0u8 };
ToBytes::to_bytes(&val, target)
}
}
macro_rules! impl_to_bytes_for_primitive {
($type:ty) => {
impl ToBytes for $type {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
let n = target
.put_bytes(&self.to_be_bytes())
.map(|()| std::mem::size_of::<$type>())?;
Ok(n)
}
}
};
}
impl_to_bytes_for_primitive!(i8);
impl_to_bytes_for_primitive!(i16);
impl_to_bytes_for_primitive!(i32);
impl_to_bytes_for_primitive!(i64);
impl_to_bytes_for_primitive!(u8);
impl_to_bytes_for_primitive!(u16);
impl_to_bytes_for_primitive!(u32);
impl_to_bytes_for_primitive!(u64);
impl_to_bytes_for_primitive!(f32);
impl_to_bytes_for_primitive!(f64);
impl ToBytes for usize {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
ToBytes::to_bytes(&(*self as u64), target)
}
}
impl ToBytes for char {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
ToBytes::to_bytes(&(*self as u32), target)
}
}
impl<TB: ToBytes, const COUNT: usize> ToBytes for [TB; COUNT] {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
let mut n = 0;
for b in self.iter().take(COUNT) {
n += ToBytes::to_bytes(b, target)?;
}
Ok(n)
}
}
impl<TB: ToBytes> ToBytes for &[TB] {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
let mut n = self.len().to_bytes(target)?;
for i in 0..self.len() {
n += self[i].to_bytes(target)?;
}
Ok(n)
}
}
impl<TB: ToBytes> ToBytes for Vec<TB> {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
ToBytes::to_bytes(&self.as_slice(), target)
}
}
impl ToBytes for String {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
ToBytes::to_bytes(&self.as_str(), target)
}
}
impl ToBytes for &str {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
self.as_bytes().to_bytes(target)
}
}
impl<T: ToBytes> ToBytes for Option<T> {
fn to_bytes<PB: PutBytes>(&self, target: &mut PB) -> Result<usize, Error> {
match self {
Some(val) => Ok(ToBytes::to_bytes(&1u8, target)? + ToBytes::to_bytes(val, target)?),
None => ToBytes::to_bytes(&0u8, target),
}
}
}
impl ToBytes for () {
fn to_bytes<PB: PutBytes>(&self, _target: &mut PB) -> Result<usize, Error> {
Ok(0)
}
}