use bincode::SizeLimit;
use bincode::rustc_serialize::{DecodingError, EncodingError, decode_from, encode, encode_into,
encoded_size, encoded_size_bounded};
use rustc_serialize::{Decodable, Encodable};
use std::io::{Cursor, Read, Write};
quick_error! {
#[derive(Debug)]
pub enum SerialisationError {
Serialise(err: EncodingError) {
description("Serialise error")
display("Serialise error: {}", err)
cause(err)
from()
}
Deserialise(err: DecodingError) {
description("Deserialise error")
display("Deserialise error: {}", err)
cause(err)
from()
}
}
}
pub fn serialise<T>(data: &T) -> Result<Vec<u8>, SerialisationError>
where T: Encodable
{
encode(data, SizeLimit::Infinite).map_err(From::from)
}
pub fn serialise_with_limit<T>(data: &T,
size_limit: SizeLimit)
-> Result<Vec<u8>, SerialisationError>
where T: Encodable
{
encode(data, size_limit).map_err(From::from)
}
pub fn deserialise<T>(data: &[u8]) -> Result<T, SerialisationError>
where T: Decodable
{
let mut data = Cursor::new(data);
deserialise_from(&mut data)
}
pub fn deserialise_with_limit<T>(data: &[u8],
size_limit: SizeLimit)
-> Result<T, SerialisationError>
where T: Decodable
{
let mut data = Cursor::new(data);
deserialise_from_with_limit(&mut data, size_limit)
}
pub fn serialise_into<T: Encodable, W: Write>(data: &T,
write: &mut W)
-> Result<(), SerialisationError> {
encode_into(data, write, SizeLimit::Infinite).map_err(From::from)
}
pub fn serialise_into_with_limit<T: Encodable, W: Write>(data: &T,
write: &mut W,
size_limit: SizeLimit)
-> Result<(), SerialisationError> {
encode_into(data, write, size_limit).map_err(From::from)
}
pub fn deserialise_from<R: Read, T: Decodable>(read: &mut R) -> Result<T, SerialisationError> {
decode_from(read, SizeLimit::Infinite).map_err(From::from)
}
pub fn deserialise_from_with_limit<R: Read, T: Decodable>(read: &mut R,
size_limit: SizeLimit)
-> Result<T, SerialisationError> {
decode_from(read, size_limit).map_err(From::from)
}
pub fn serialised_size<T: Encodable>(data: &T) -> u64 {
encoded_size(data)
}
pub fn serialised_size_with_limit<T: Encodable>(data: &T, max: u64) -> Option<u64> {
encoded_size_bounded(data, max)
}
#[cfg(test)]
mod tests {
use bincode::SizeLimit;
use bincode::rustc_serialize::{DecodingError, EncodingError};
use std::io::Cursor;
use super::*;
#[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 = SizeLimit::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!(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(EncodingError::SizeLimit)) =
serialise_with_limit(&original_data, upper_limit) {} else {
panic!("Expected size limit error.");
}
let mut buffer = vec![];
if let Err(SerialisationError::Serialise(EncodingError::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(DecodingError::SizeLimit)) =
deserialise_with_limit::<Vec<u64>>(&excessive, upper_limit) {} else {
panic!("Expected size limit error.");
}
serialised = Cursor::new(excessive);
if let Err(SerialisationError::Deserialise(DecodingError::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());
}
}