mod deserializer;
mod error;
mod serializer;
use serde::{de::Deserialize, de::DeserializeOwned, Serialize};
use binary_stream::{BinaryReader, BinaryWriter, Endian, MemoryStream, SliceStream};
pub use binary_stream;
pub use {deserializer::Deserializer, error::Error, serializer::Serializer};
pub type Result<T> = std::result::Result<T, Error>;
pub fn to_vec<T>(value: &T, endian: Endian) -> Result<Vec<u8>>
where
T: ?Sized + Serialize,
{
let mut stream = MemoryStream::new();
let writer = BinaryWriter::new(&mut stream, endian);
let mut serializer = Serializer { writer };
value.serialize(&mut serializer)?;
Ok(stream.into())
}
pub fn from_vec<T>(value: Vec<u8>, endian: Endian) -> Result<T>
where
T: DeserializeOwned,
{
from_slice(&value, endian)
}
pub fn from_slice<T>(value: &[u8], endian: Endian) -> Result<T>
where
T: DeserializeOwned,
{
let mut stream = SliceStream::new(value);
let reader = BinaryReader::new(&mut stream, endian);
let mut deserializer = Deserializer { reader };
let value: T = Deserialize::deserialize(&mut deserializer)?;
Ok(value)
}
pub fn encode(encodable: &impl Encode, endian: Endian) -> Result<Vec<u8>> {
let mut stream = MemoryStream::new();
let writer = BinaryWriter::new(&mut stream, endian);
let mut serializer = Serializer { writer };
encodable.encode(&mut serializer)?;
Ok(stream.into())
}
pub fn decode<T: Decode + Default>(buffer: &[u8], endian: Endian) -> Result<T> {
let mut stream = SliceStream::new(buffer);
let reader = BinaryReader::new(&mut stream, endian);
let mut deserializer = Deserializer { reader };
let mut decoded: T = T::default();
decoded.decode(&mut deserializer)?;
Ok(decoded)
}
pub trait Encode {
fn encode(&self, ser: &mut Serializer) -> Result<()>;
}
pub trait Decode {
fn decode(&mut self, de: &mut Deserializer) -> Result<()>;
}
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[test]
fn serde_unit() -> Result<()> {
let val = ();
let buffer = to_vec(&val, Default::default())?;
let res: () = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_option_none() -> Result<()> {
let val: Option<u8> = None;
let buffer = to_vec(&val, Default::default())?;
let res: Option<u8> = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_option_some() -> Result<()> {
let val = Some(1u8);
let buffer = to_vec(&val, Default::default())?;
let res: Option<u8> = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_string() -> Result<()> {
let val = String::from("foo");
let buffer = to_vec(&val, Default::default())?;
let res: String = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_char() -> Result<()> {
let val = 'x';
let buffer = to_vec(&val, Default::default())?;
let res: char = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_bool_true() -> Result<()> {
let val = true;
let buffer = to_vec(&val, Default::default())?;
let res: bool = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_bool_false() -> Result<()> {
let val = false;
let buffer = to_vec(&val, Default::default())?;
let res: bool = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_u8() -> Result<()> {
let val = 8u8;
let buffer = to_vec(&val, Default::default())?;
let res: u8 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_u16() -> Result<()> {
let val = 16u16;
let buffer = to_vec(&val, Default::default())?;
let res: u16 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_u32() -> Result<()> {
let val = 32u32;
let buffer = to_vec(&val, Default::default())?;
let res: u32 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_u64() -> Result<()> {
let val = 64u64;
let buffer = to_vec(&val, Default::default())?;
let res: u64 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_usize() -> Result<()> {
let val = usize::MAX;
let buffer = to_vec(&val, Default::default())?;
let res: usize = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_i8() -> Result<()> {
let val = -8i8;
let buffer = to_vec(&val, Default::default())?;
let res: i8 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_i16() -> Result<()> {
let val = -16i16;
let buffer = to_vec(&val, Default::default())?;
let res: i16 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_i32() -> Result<()> {
let val = -32i32;
let buffer = to_vec(&val, Default::default())?;
let res: i32 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_i64() -> Result<()> {
let val = -64i64;
let buffer = to_vec(&val, Default::default())?;
let res: i64 = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_isize() -> Result<()> {
let val = isize::MIN;
let buffer = to_vec(&val, Default::default())?;
let res: isize = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_vec() -> Result<()> {
let val = vec![1u8, 2u8, 3u8];
let buffer = to_vec(&val, Default::default())?;
let res: Vec<u8> = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_tuple() -> Result<()> {
let val = (1u8, String::from("foo"));
let buffer = to_vec(&val, Default::default())?;
let res: (u8, String) = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_map() -> Result<()> {
let mut val = HashMap::new();
val.insert("foo".to_string(), 1u8);
val.insert("bar".to_string(), 2u8);
let buffer = to_vec(&val, Default::default())?;
let res: HashMap<String, u8> = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
struct SimpleStruct {
x: u32,
y: u32,
}
#[test]
fn serde_struct() -> Result<()> {
let val = SimpleStruct { x: 1, y: 2 };
let buffer = to_vec(&val, Default::default())?;
let res: SimpleStruct = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum E {
Unit,
NewType(u32),
Tuple(u32, u32),
Struct { a: u32 },
}
#[test]
fn serde_enum_unit() -> Result<()> {
let val = E::Unit;
let buffer = to_vec(&val, Default::default())?;
let res: E = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_enum_newtype() -> Result<()> {
let val = E::NewType(1);
let buffer = to_vec(&val, Default::default())?;
let res: E = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_enum_tuple() -> Result<()> {
let val = E::Tuple(1, 2);
let buffer = to_vec(&val, Default::default())?;
let res: E = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
#[test]
fn serde_enum_struct() -> Result<()> {
let val = E::Struct { a: 1 };
let buffer = to_vec(&val, Default::default())?;
let res: E = from_vec(buffer, Default::default())?;
assert_eq!(val, res);
Ok(())
}
const MAGIC: [u8; 4] = [84, 79, 68, 79];
#[derive(Debug, Eq, PartialEq)]
struct TodoList {
magic: [u8; 4],
todos: Vec<Todo>,
}
impl Default for TodoList {
fn default() -> Self {
Self {
magic: MAGIC,
todos: vec![],
}
}
}
impl Encode for TodoList {
fn encode(&self, ser: &mut Serializer) -> super::Result<()> {
ser.writer.write_bytes(self.magic)?;
self.todos.serialize(ser)?;
Ok(())
}
}
impl Decode for TodoList {
fn decode(&mut self, de: &mut Deserializer) -> super::Result<()> {
self.magic = de.reader.read_bytes(4)?.as_slice().try_into()?;
if self.magic != MAGIC {
return Err(Error::Custom("not a todo list binary file".to_string()));
}
self.todos = Deserialize::deserialize(de)?;
Ok(())
}
}
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq)]
struct Todo {
name: String,
note: String,
}
#[test]
fn serde_mixed() -> Result<()> {
let todos = vec![Todo {
name: String::from("foo"),
note: String::from("bar"),
}];
let list = TodoList {
magic: [84, 79, 68, 79],
todos,
};
let buffer = encode(&list, Default::default())?;
let decoded: TodoList = decode(&buffer, Default::default())?;
assert_eq!(list, decoded);
Ok(())
}
}