use bincode::{
deserialize, deserialize_from, serialize, serialize_into, serialized_size,
serialized_size_bounded, Bounded, ErrorKind, Infinite,
};
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::io::{Cursor, Read, Write};
quick_error! {
#[derive(Debug)]
pub enum SerialisationError {
Serialise(err: ErrorKind) {
description("Serialise error")
display("Serialise error: {}", err)
cause(err)
}
Deserialise(err: ErrorKind) {
description("Deserialise error")
display("Deserialise error: {}", err)
cause(err)
}
DeserialiseExtraBytes {
description("DeserialiseExtraBytes error")
display("Deserialise error: Not all bytes of slice consumed")
}
}
}
pub fn serialise<T>(data: &T) -> Result<Vec<u8>, SerialisationError>
where
T: Serialize,
{
serialize(data, Infinite).map_err(|e| SerialisationError::Serialise(*e))
}
pub fn serialise_with_limit<T>(data: &T, size_limit: Bounded) -> Result<Vec<u8>, SerialisationError>
where
T: Serialize,
{
serialize(data, size_limit).map_err(|e| SerialisationError::Serialise(*e))
}
pub fn deserialise<T>(data: &[u8]) -> Result<T, SerialisationError>
where
T: Serialize + DeserializeOwned,
{
let value = deserialize(data).map_err(|e| SerialisationError::Deserialise(*e))?;
if serialized_size(&value) != data.len() as u64 {
return Err(SerialisationError::DeserialiseExtraBytes);
}
Ok(value)
}
pub fn deserialise_with_limit<T>(data: &[u8], size_limit: Bounded) -> Result<T, SerialisationError>
where
T: DeserializeOwned,
{
let mut cursor = Cursor::new(data);
let value = deserialize_from(&mut cursor, size_limit)
.map_err(|e| SerialisationError::Deserialise(*e))?;
if cursor.position() != data.len() as u64 {
return Err(SerialisationError::DeserialiseExtraBytes);
}
Ok(value)
}
pub fn serialise_into<T: Serialize, W: Write>(
data: &T,
write: &mut W,
) -> Result<(), SerialisationError> {
serialize_into(write, data, Infinite).map_err(|e| SerialisationError::Serialise(*e))
}
pub fn serialise_into_with_limit<T: Serialize, W: Write>(
data: &T,
write: &mut W,
size_limit: Bounded,
) -> Result<(), SerialisationError> {
serialize_into(write, data, size_limit).map_err(|e| SerialisationError::Serialise(*e))
}
pub fn deserialise_from<R: Read, T: DeserializeOwned>(
read: &mut R,
) -> Result<T, SerialisationError> {
deserialize_from(read, Infinite).map_err(|e| SerialisationError::Deserialise(*e))
}
pub fn deserialise_from_with_limit<R: Read, T: DeserializeOwned>(
read: &mut R,
size_limit: Bounded,
) -> Result<T, SerialisationError> {
deserialize_from(read, size_limit).map_err(|e| SerialisationError::Deserialise(*e))
}
pub fn serialised_size<T: Serialize>(data: &T) -> u64 {
serialized_size(data)
}
pub fn serialised_size_with_limit<T: Serialize>(data: &T, max: u64) -> Option<u64> {
serialized_size_bounded(data, max)
}
#[cfg(test)]
mod tests {
use super::*;
use bincode::{Bounded, ErrorKind};
use serde::de::{self, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use std::io::Cursor;
#[test]
fn serialise_deserialise() {
let original_data = (
vec![0u8, 1, 3, 9],
vec![-1i64, 888, -8765],
"SomeString".to_string(),
);
let serialised_data = unwrap!(serialise(&original_data));
let deserialised_data: (Vec<u8>, Vec<i64>, String) = unwrap!(deserialise(&serialised_data));
assert_eq!(original_data, deserialised_data);
let serialised_string = unwrap!(serialise(&"Another string".to_string()));
match unwrap_err!(deserialise::<u64>(&serialised_string)) {
SerialisationError::DeserialiseExtraBytes => (),
err => panic!("{:?}", err),
}
}
#[test]
fn serialise_into_deserialise_from() {
let original_data = (
vec![0u8, 1, 3, 9],
vec![-1i64, 888, -8765],
"SomeString".to_string(),
);
let mut serialised_data = vec![];
unwrap!(serialise_into(&original_data, &mut serialised_data));
let mut serialised = Cursor::new(serialised_data);
let deserialised_data: (Vec<u8>, Vec<i64>, String) =
unwrap!(deserialise_from(&mut serialised));
assert_eq!(original_data, deserialised_data);
}
#[test]
fn upper_limit() {
let upper_limit = Bounded(64);
let mut original_data = (1u64..8).collect::<Vec<_>>();
let mut serialised_data = unwrap!(serialise_with_limit(&original_data, upper_limit));
let mut deserialised_data: Vec<u64> = unwrap!(deserialise(&serialised_data));
assert_eq!(original_data, deserialised_data);
serialised_data.clear();
unwrap!(serialise_into_with_limit(
&original_data,
&mut serialised_data,
upper_limit,
));
let mut serialised = Cursor::new(serialised_data);
deserialised_data = unwrap!(deserialise_from(&mut serialised));
assert_eq!(original_data, deserialised_data);
original_data.push(0);
if let Err(SerialisationError::Serialise(ErrorKind::SizeLimit)) =
serialise_with_limit(&original_data, upper_limit)
{
} else {
panic!("Expected size limit error.");
}
let mut buffer = vec![];
if let Err(SerialisationError::Serialise(ErrorKind::SizeLimit)) =
serialise_into_with_limit(&original_data, &mut buffer, upper_limit)
{
} else {
panic!("Expected size limit error.");
}
let excessive = unwrap!(serialise(&original_data));
if let Err(SerialisationError::Deserialise(ErrorKind::SizeLimit)) =
deserialise_with_limit::<Vec<u64>>(&excessive, upper_limit)
{
} else {
panic!("Expected size limit error.");
}
serialised = Cursor::new(excessive);
if let Err(SerialisationError::Deserialise(ErrorKind::SizeLimit)) =
deserialise_from_with_limit::<Cursor<_>, Vec<u64>>(&mut serialised, upper_limit)
{
} else {
panic!("Expected size limit error.");
}
}
#[test]
fn sizes() {
let data = (1u64..8).collect::<Vec<_>>();
assert_eq!(serialised_size(&data), 64);
assert_eq!(serialised_size_with_limit(&data, 100), Some(64));
assert_eq!(serialised_size_with_limit(&data, 64), Some(64));
assert!(serialised_size_with_limit(&data, 63).is_none());
}
#[derive(PartialEq, Eq, Debug)]
struct Wrapper([u8; 1]);
impl Serialize for Wrapper {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_bytes(&self.0[..])
}
}
impl<'de> Deserialize<'de> for Wrapper {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Wrapper, D::Error> {
struct WrapperVisitor;
impl<'de> Visitor<'de> for WrapperVisitor {
type Value = Wrapper;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Wrapper")
}
fn visit_bytes<E: de::Error>(self, value: &[u8]) -> Result<Self::Value, E> {
if value.len() != 1 {
return Err(de::Error::invalid_length(value.len(), &self));
}
Ok(Wrapper([value[0]]))
}
}
deserializer.deserialize_bytes(WrapperVisitor)
}
}
#[test]
fn deserialize_bytes() {
let wrapper = Wrapper([255]);
let serialised_wrapper = unwrap!(serialise(&wrapper));
assert_eq!(serialised_wrapper, [1, 0, 0, 0, 0, 0, 0, 0, 255]);
let deserialised_wrapper: Wrapper = unwrap!(deserialise(&serialised_wrapper));
assert_eq!(wrapper, deserialised_wrapper);
let tampered = [255u8; 9];
match unwrap_err!(deserialise::<Wrapper>(&tampered)) {
SerialisationError::Deserialise(_) => (),
err => panic!("{:?}", err),
}
match unwrap_err!(deserialise::<Wrapper>(&[1, 0, 0, 0, 0, 0, 0, 0, 255, 255])) {
SerialisationError::DeserialiseExtraBytes => (),
err => panic!("{:?}", err),
}
}
}