#![no_std]
#![allow(
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_sign_loss,
clippy::module_name_repetitions,
clippy::similar_names
)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std as alloc;
mod de;
mod error;
mod ser;
pub use self::error::{Error, Result};
use byteio::{prelude::*, Writer};
use serde::{Deserialize, Serialize};
pub trait Dump {
fn dump_into_bytes<W: WriteBytes>(&self, writer: W) -> crate::Result<usize>;
fn dump_into_be_bytes<W: WriteBytes>(&self, writer: W) -> crate::Result<usize>;
fn dump_into_le_bytes<W: WriteBytes>(&self, writer: W) -> crate::Result<usize>;
}
impl<T: Serialize> Dump for T {
fn dump_into_bytes<W: WriteBytes>(&self, writer: W) -> crate::Result<usize> {
#[cfg(target_endian = "big")]
let n = self.dump_into_be_bytes(writer)?;
#[cfg(target_endian = "little")]
let n = self.dump_into_le_bytes(writer)?;
Ok(n)
}
fn dump_into_be_bytes<W: WriteBytes>(&self, writer: W) -> crate::Result<usize> {
let fb = crate::ser::FunctionBank::new(
<Writer<W> as WriteBytesExt>::try_write_i8,
<Writer<W> as WriteBytesExt>::try_write_i16_be,
<Writer<W> as WriteBytesExt>::try_write_i32_be,
<Writer<W> as WriteBytesExt>::try_write_i64_be,
<Writer<W> as WriteBytesExt>::try_write_u8,
<Writer<W> as WriteBytesExt>::try_write_u16_be,
<Writer<W> as WriteBytesExt>::try_write_u32_be,
<Writer<W> as WriteBytesExt>::try_write_u64_be,
<Writer<W> as WriteBytesExt>::try_write_f32_be,
<Writer<W> as WriteBytesExt>::try_write_f64_be,
);
let writer = Writer::new(writer);
let mut serializer = crate::ser::Serializer::new(writer, fb);
self.serialize(&mut serializer)?;
let writer = serializer.into_inner();
Ok(writer.num_bytes_written())
}
fn dump_into_le_bytes<W: WriteBytes>(&self, writer: W) -> crate::Result<usize> {
let fb = crate::ser::FunctionBank::new(
<Writer<W> as WriteBytesExt>::try_write_i8,
<Writer<W> as WriteBytesExt>::try_write_i16_le,
<Writer<W> as WriteBytesExt>::try_write_i32_le,
<Writer<W> as WriteBytesExt>::try_write_i64_le,
<Writer<W> as WriteBytesExt>::try_write_u8,
<Writer<W> as WriteBytesExt>::try_write_u16_le,
<Writer<W> as WriteBytesExt>::try_write_u32_le,
<Writer<W> as WriteBytesExt>::try_write_u64_le,
<Writer<W> as WriteBytesExt>::try_write_f32_le,
<Writer<W> as WriteBytesExt>::try_write_f64_le,
);
let writer = Writer::new(writer);
let mut serializer = crate::ser::Serializer::new(writer, fb);
self.serialize(&mut serializer)?;
let writer = serializer.into_inner();
Ok(writer.num_bytes_written())
}
}
pub trait Load<'a>
where
Self: Sized,
{
fn load_from_bytes<R: ReadBytes<'a>>(reader: R) -> crate::Result<Self>;
fn load_from_be_bytes<R: ReadBytes<'a>>(reader: R) -> crate::Result<Self>;
fn load_from_le_bytes<R: ReadBytes<'a>>(reader: R) -> crate::Result<Self>;
}
impl<'a, T: Deserialize<'a>> Load<'a> for T {
fn load_from_bytes<R: ReadBytes<'a>>(reader: R) -> crate::Result<Self> {
#[cfg(target_endian = "big")]
let t = T::load_from_be_bytes(reader)?;
#[cfg(target_endian = "little")]
let t = T::load_from_le_bytes(reader)?;
Ok(t)
}
fn load_from_be_bytes<R: ReadBytes<'a>>(reader: R) -> crate::Result<Self> {
let fb = crate::de::FunctionBank::new(
<R as ReadBytesExt>::try_read_i8,
<R as ReadBytesExt>::try_read_i16_be,
<R as ReadBytesExt>::try_read_i32_be,
<R as ReadBytesExt>::try_read_i64_be,
<R as ReadBytesExt>::try_read_u8,
<R as ReadBytesExt>::try_read_u16_be,
<R as ReadBytesExt>::try_read_u32_be,
<R as ReadBytesExt>::try_read_u64_be,
<R as ReadBytesExt>::try_read_f32_be,
<R as ReadBytesExt>::try_read_f64_be,
);
let mut deserializer = crate::de::Deserializer::new(reader, fb);
Self::deserialize(&mut deserializer)
}
fn load_from_le_bytes<R: ReadBytes<'a>>(reader: R) -> crate::Result<Self> {
let fb = crate::de::FunctionBank::new(
<R as ReadBytesExt>::try_read_i8,
<R as ReadBytesExt>::try_read_i16_le,
<R as ReadBytesExt>::try_read_i32_le,
<R as ReadBytesExt>::try_read_i64_le,
<R as ReadBytesExt>::try_read_u8,
<R as ReadBytesExt>::try_read_u16_le,
<R as ReadBytesExt>::try_read_u32_le,
<R as ReadBytesExt>::try_read_u64_le,
<R as ReadBytesExt>::try_read_f32_le,
<R as ReadBytesExt>::try_read_f64_le,
);
let mut deserializer = crate::de::Deserializer::new(reader, fb);
Self::deserialize(&mut deserializer)
}
}
#[cfg(test)]
mod test {
use super::*;
#[cfg(any(feature = "std", feature = "alloc"))]
use alloc::vec::Vec;
use serde_derive::{Deserialize, Serialize};
#[derive(Default, Serialize, Deserialize)]
struct Foo {
bar: i16,
baz: i64,
qux: f32,
}
const FOO_SERIALIZED_LENGTH: usize = 14;
#[test]
fn serialize_into_u8_slice_consumed_bytes() {
let mut buf = [0u8; FOO_SERIALIZED_LENGTH];
let foo = Foo::default();
let bytes_written = foo.dump_into_bytes(&mut buf[..]).unwrap();
assert_eq!(bytes_written, FOO_SERIALIZED_LENGTH);
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[test]
fn serialize_into_u8_vec_consumed_slice() {
let mut buf = Vec::new();
let foo = Foo::default();
let bytes_written = foo.dump_into_bytes(&mut buf).unwrap();
assert_eq!(bytes_written, FOO_SERIALIZED_LENGTH);
}
}