use bincode::{self, Bounded, Infinite, deserialize_from, serialize, serialize_into,
serialized_size, serialized_size_bounded};
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::io::{Cursor, Read, Write};
quick_error! {
#[derive(Debug)]
pub enum SerialisationError {
Serialise(err: bincode::ErrorKind) {
description("Serialise error")
display("Serialise error: {}", err)
cause(err)
}
Deserialise(err: bincode::ErrorKind) {
description("Deserialise error")
display("Deserialise error: {}", err)
cause(err)
}
}
}
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: DeserializeOwned
{
let mut data = Cursor::new(data);
deserialize_from(&mut data, Infinite).map_err(|e| SerialisationError::Deserialise(*e))
}
pub fn deserialise_with_limit<T>(data: &[u8], size_limit: Bounded) -> Result<T, SerialisationError>
where T: DeserializeOwned
{
let mut data = Cursor::new(data);
deserialize_from(&mut data, size_limit).map_err(|e| SerialisationError::Deserialise(*e))
}
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 std::io::Cursor;
#[test]
fn serialise_deserialise() {
let original_data = (vec![0u8, 1, 3, 9], vec![-1i64, 888, -8765], "Some-String".to_owned());
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);
}
#[test]
fn serialise_into_deserialise_from() {
let original_data = (vec![0u8, 1, 3, 9], vec![-1i64, 888, -8765], "Some-String".to_owned());
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());
}
}