use std::io::Result as Res;
use std::io::Write;
use crate::{BigEndian, Endianness, EWrite, LittleEndian};
pub trait Serialize<E: Endianness, W> {
fn serialize(self, writer: &mut W) -> Res<()>;
}
impl<E: Endianness, W: Write> Serialize<E, W> for &[u8] {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(self)
}
}
impl<E: Endianness, W: Write> Serialize<E, W> for &Vec<u8> {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(&self[..])
}
}
impl<E: Endianness, W: Write> Serialize<E, W> for bool {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(&(self as u8).to_ne_bytes())
}
}
impl<E: Endianness, W: Write> Serialize<E, W> for u8 {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(&self.to_ne_bytes())
}
}
impl<E: Endianness, W: Write> Serialize<E, W> for i8 {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(&self.to_ne_bytes())
}
}
macro_rules! impl_int {
($t:ident) => {
impl<W: Write> Serialize<BigEndian, W> for $t {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(&self.to_be_bytes())
}
}
impl<W: Write> Serialize<LittleEndian, W> for $t {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write_all(&self.to_le_bytes())
}
}
#[cfg(test)]
mod $t {
use std::mem::size_of;
#[test]
fn test() {
let integer: u128 = 0xbaadf00dbaadf00dbaadf00dbaadf00d;
let bytes = b"\x0d\xf0\xad\xba\x0d\xf0\xad\xba\x0d\xf0\xad\xba\x0d\xf0\xad\xba";
{
use crate::BEWrite;
let mut writer = vec![];
writer.write((integer as $t).to_be()).unwrap();
assert_eq!(&writer[..], &bytes[..size_of::<$t>()]);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write((integer as $t).to_le()).unwrap();
assert_eq!(&writer[..], &bytes[..size_of::<$t>()]);
}
}
}
}
}
impl_int!(u16);
impl_int!(u32);
impl_int!(u64);
impl_int!(u128);
impl_int!(i16);
impl_int!(i32);
impl_int!(i64);
impl_int!(i128);
impl<E: Endianness, W: EWrite<E>> Serialize<E, W> for f32 where u32: Serialize<E, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write(self.to_bits())
}
}
impl<E: Endianness, W: EWrite<E>> Serialize<E, W> for f64 where u64: Serialize<E, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write(self.to_bits())
}
}
#[cfg(test)]
mod tests {
use std::io::Result as Res;
#[test]
fn write_bool_false() {
let data = b"\x00";
let val = false;
{
use crate::BEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
}
#[test]
fn write_bool_true() {
let data = b"\x01";
let val = true;
{
use crate::BEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
}
#[test]
fn write_i8() {
let data = b"\x80";
let val = i8::min_value();
{
use crate::BEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
}
#[test]
fn write_u8() {
let data = b"\xff";
let val = u8::max_value();
{
use crate::BEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write(val).unwrap();
assert_eq!(writer, data);
}
}
#[test]
fn write_f32() {
let data = b"\x44\x20\xa7\x44";
{
use crate::BEWrite;
let mut writer = vec![];
writer.write(642.613525390625f32).unwrap();
assert_eq!(writer, data);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write(1337.0083007812f32).unwrap();
assert_eq!(writer, data);
}
}
#[test]
fn write_f64() {
let data = b"\x40\x94\x7a\x14\xae\xe5\x94\x40";
{
use crate::BEWrite;
let mut writer = vec![];
writer.write(1310.5201984283194f64).unwrap();
assert_eq!(writer, data);
}
{
use crate::LEWrite;
let mut writer = vec![];
writer.write(1337.4199999955163f64).unwrap();
assert_eq!(writer, data);
}
}
#[test]
fn write_struct_forced() {
struct Test {
a: u16,
}
{
use crate::{Endianness, EWrite, Serialize};
impl<E: Endianness, W: EWrite<E>> Serialize<E, W> for Test where u16: Serialize<E, W> {
fn serialize(self, writer: &mut W) -> Res<()> {
writer.write(self.a)?;
Ok(())
}
}
}
use crate::LEWrite;
let data = b"\xba\xad";
let mut writer = vec![];
writer.write_be(Test { a: 0xbaad }).unwrap();
assert_eq!(&writer[..], data);
}
}