use errors::{BVExpectedSize, ByteVecError};
use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use traits::{ByteDecodable, ByteEncodable};
use {BVDecodeResult, BVEncodeResult, BVSize};
macro_rules! validate_collection {
($byte_vec:ident, $index:ident, $len:ident, $size_vec:ident, $ret:expr) => {{
if $byte_vec.len() >= Size::get_size_of().as_usize() {
$len = (Size::decode::<Size>(&$byte_vec[..Size::get_size_of().as_usize()]))?.as_usize();
$index = Size::get_size_of().as_usize();
let sizes_len = $len * Size::get_size_of().as_usize();
if $byte_vec[Size::get_size_of().as_usize()..].len() >= sizes_len {
$size_vec = Vec::new();
for _ in 0..$len {
$size_vec.push(
(Size::decode::<Size>(
&$byte_vec[$index..$index + Size::get_size_of().as_usize()],
))?,
);
$index += Size::get_size_of().as_usize();
}
let body_size = $size_vec
.iter()
.fold(0, |acc, ref size| acc + size.as_usize());
if body_size == $byte_vec[Size::get_size_of().as_usize() + sizes_len..].len() {
$ret
} else {
Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::EqualTo(
Size::get_size_of().as_usize() + sizes_len + body_size,
),
actual: $byte_vec.len(),
})
}
} else {
Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize() + sizes_len),
actual: $byte_vec.len(),
})
}
} else {
Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize()),
actual: $byte_vec.len(),
})
}
}};
}
impl ByteEncodable for str {
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
if self.len() <= Size::max_value().as_usize() {
Some(Size::from_usize(self.len()))
} else {
None
}
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
if self.get_size::<Size>().is_some() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&self.as_bytes().to_vec());
Ok(bytes)
} else {
Err(ByteVecError::OverflowError)
}
}
}
impl<'a> ByteEncodable for &'a str {
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
(**self).get_size::<Size>()
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
(**self).encode::<Size>()
}
}
impl ByteEncodable for String {
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
(**self).get_size::<Size>()
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
(**self).encode::<Size>()
}
}
impl ByteDecodable for String {
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<String>
where
Size: BVSize + ByteDecodable,
{
Ok((::std::str::from_utf8(bytes))?.to_string())
}
}
impl<T> ByteEncodable for Option<T>
where
T: ByteEncodable,
{
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
match self {
Some(val) => val.get_size::<Size>()?.checked_add(Size::from_usize(1)),
None => Some(Size::from_usize(1)),
}
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
match self {
Some(val) => Ok(std::iter::once(1u8)
.chain((val.encode::<Size>())?.into_iter())
.collect()),
None => Ok(vec![0u8]),
}
}
}
impl<T> ByteDecodable for Option<T>
where
T: ByteDecodable,
{
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<Option<T>>
where
Size: BVSize + ByteDecodable,
{
if bytes.is_empty() {
return Ok(None);
} else if (bytes.len() == 1) && (bytes[0] == 0u8) {
return Ok(None);
}
Ok(Some(T::decode::<Size>(&bytes[1..])?))
}
}
macro_rules! collection_encode_impl {
() => {
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
self.iter()
.fold(Some(Size::from_usize(0)), |acc, elem| {
acc.and_then(|acc: Size| {
(&elem).get_size::<Size>().and_then(|size| {
acc.checked_add(size)
.and_then(|acc_size| acc_size.checked_add(Size::get_size_of()))
})
})
})
.and_then(|total: Size| total.checked_add(Size::get_size_of()))
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
if self.get_size::<Size>().is_some() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&((Size::from_usize(self.len())).encode::<Size>())?);
for elem in self {
bytes.extend_from_slice(
&((&elem).get_size::<Size>().unwrap().encode::<Size>())?,
);
}
for elem in self {
bytes.extend_from_slice(&((&elem).encode::<Size>())?);
}
Ok(bytes)
} else {
Err(ByteVecError::OverflowError)
}
}
};
}
impl<T> ByteEncodable for Vec<T>
where
T: ByteEncodable,
{
collection_encode_impl!();
}
impl<T> ByteDecodable for Vec<T>
where
T: ByteDecodable,
{
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<Vec<T>>
where
Size: BVSize + ByteDecodable,
{
let len;
let mut index;
let mut sizes;
validate_collection!(bytes, index, len, sizes, {
let mut vec = Vec::with_capacity(len);
for size in sizes.into_iter() {
vec.push((T::decode::<Size>(&bytes[index..index + size.as_usize()]))?);
index += size.as_usize();
}
Ok(vec)
})
}
}
impl<T> ByteEncodable for [T]
where
T: ByteEncodable,
{
collection_encode_impl!();
}
impl<T> ByteEncodable for HashSet<T>
where
T: ByteEncodable + Eq + Hash,
{
collection_encode_impl!();
}
impl<T> ByteDecodable for HashSet<T>
where
T: ByteDecodable + Eq + Hash,
{
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<HashSet<T>>
where
Size: BVSize + ByteDecodable,
{
let len;
let mut index;
let mut sizes;
validate_collection!(bytes, index, len, sizes, {
let mut set = HashSet::with_capacity(len);
for size in sizes.into_iter() {
set.insert((T::decode::<Size>(&bytes[index..index + size.as_usize()]))?);
index += size.as_usize();
}
Ok(set)
})
}
}
impl<K, V> ByteEncodable for HashMap<K, V>
where
K: ByteEncodable + Hash + Eq,
V: ByteEncodable,
{
collection_encode_impl!();
}
impl<K, V> ByteDecodable for HashMap<K, V>
where
K: ByteDecodable + Hash + Eq,
V: ByteDecodable,
{
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<HashMap<K, V>>
where
Size: BVSize + ByteDecodable,
{
let len;
let mut index;
let mut sizes;
validate_collection!(bytes, index, len, sizes, {
let mut map = HashMap::with_capacity(len);
for size in sizes.into_iter() {
let (key, value) =
(<(K, V)>::decode::<Size>(&bytes[index..index + size.as_usize()]))?;
map.insert(key, value);
index += size.as_usize();
}
Ok(map)
})
}
}
macro_rules! tuple_impls {
($t:ident: $elem:ident) => {
impl<$t,> ByteEncodable for ($t,)
where $t: ByteEncodable
{
fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
(&(&self.0)).get_size::<Size>()
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
(&(&self.0)).encode::<Size>()
}
}
impl<'a, $t,> ByteEncodable for &'a (&'a $t,)
where $t: ByteEncodable
{
fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
self.0.get_size::<Size>().and_then(|elem_size|
elem_size.checked_add(Size::get_size_of()))
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
if self.get_size::<Size>().is_some() {
let mut bytes = Vec::new();
bytes.extend_from_slice(&(
self.0.get_size::<Size>().unwrap().encode::<Size>())?);
bytes.extend_from_slice(&(self.0.encode::<Size>())?);
Ok(bytes)
} else {
Err(ByteVecError::OverflowError)
}
}
}
impl<$t,> ByteDecodable for ($t,)
where $t: ByteDecodable
{
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<($t,)>
where Size: BVSize + ByteDecodable
{
let size;
if bytes.len() >= Size::get_size_of().as_usize() {
size = (Size::decode::<Size>(&bytes[..Size::get_size_of().as_usize()]))?;
}
else {
return Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize()),
actual: bytes.len()
});
}
if size.as_usize() == bytes[Size::get_size_of().as_usize()..].len() {
Ok((($t::decode::<Size>(&bytes[Size::get_size_of().as_usize()..]))?,))
} else {
Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::EqualTo(
Size::get_size_of().as_usize() + size.as_usize()),
actual: bytes.len()
})
}
}
}
};
($t:ident: $elem:ident, $($_t:ident: $_elem:ident),*) => {
impl<$t, $($_t,)*> ByteEncodable for ($t, $($_t),*)
where $t: ByteEncodable, $($_t: ByteEncodable),*
{
fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
let &(ref $elem, $(ref $_elem),*) = self;
(&($elem, $($_elem),*)).get_size::<Size>()
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
let &(ref $elem, $(ref $_elem),*) = self;
(&($elem, $($_elem),*)).encode::<Size>()
}
}
impl<'a, $t, $($_t,)*> ByteEncodable for &'a (&'a $t, $(&'a $_t),*)
where $t: ByteEncodable, $($_t: ByteEncodable),*
{
fn get_size<Size>(&self) -> Option<Size> where Size: BVSize + ByteEncodable {
let &&($elem, $($_elem),*) = self;
let mut size = Some(Size::from_usize(0));
size = size.and_then(|size: Size|
$elem.get_size::<Size>().and_then(|elem_size|
size.checked_add(elem_size).and_then(
|acc_size| acc_size.checked_add(Size::get_size_of())
)
)
);
$(
size = size.and_then(|size: Size|
$_elem.get_size::<Size>().and_then(|elem_size|
size.checked_add(elem_size).and_then(
|acc_size| acc_size.checked_add(Size::get_size_of())
)
)
);
)*
size
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>> where Size: BVSize + ByteEncodable {
if self.get_size::<Size>().is_some() {
let &&($elem, $($_elem),*) = self;
let mut bytes = Vec::new();
bytes.extend_from_slice(&(
$elem.get_size::<Size>().unwrap().encode::<Size>())?);
$(
bytes.extend_from_slice(&(
$_elem.get_size::<Size>().unwrap().encode::<Size>())?);
)*
bytes.extend_from_slice(&($elem.encode::<Size>())?);
$(
bytes.extend_from_slice(&($_elem.encode::<Size>())?);
)*
Ok(bytes)
} else {
Err(ByteVecError::OverflowError)
}
}
}
#[allow(unused_assignments)]
impl<$t, $($_t,)*> ByteDecodable for ($t, $($_t),*)
where $t: ByteDecodable, $($_t: ByteDecodable),*
{
fn decode<Size>(bytes: &[u8]) -> BVDecodeResult<($t, $($_t),*)>
where Size: BVSize + ByteDecodable
{
let mut index = 0;
let mut sizes = ::std::collections::HashMap::new();
if bytes.len() >= Size::get_size_of().as_usize() {
sizes.insert(stringify!($elem),
(Size::decode::<Size>(&bytes[..Size::get_size_of().as_usize()]))?);
index += Size::get_size_of().as_usize();
}
else {
return Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize() + index),
actual: bytes.len()
});
}
$(
if bytes[index..].len() >= Size::get_size_of().as_usize() {
sizes.insert(stringify!($_elem),
(Size::decode::<Size>(
&bytes[index..index + Size::get_size_of().as_usize()]))?);
index += Size::get_size_of().as_usize();
}
else {
return Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::MoreThan(Size::get_size_of().as_usize() + index),
actual: bytes.len()
});
}
)*
let body_size = sizes.values().fold(0, |acc, ref size| acc + size.as_usize());
if body_size == bytes[index..].len() {
Ok((
{
let elem = ($t::decode::<Size>(
&bytes[index..index + sizes[stringify!($elem)].as_usize()]))?;
index += sizes[stringify!($elem)].as_usize();
elem
},
$({
let elem = ($_t::decode::<Size>(
&bytes[index..index + sizes[stringify!($_elem)].as_usize()]))?;
index += sizes[stringify!($_elem)].as_usize();
elem
}),*
))
} else {
Err(ByteVecError::BadSizeDecodeError {
expected: BVExpectedSize::EqualTo(
Size::get_size_of().as_usize() * sizes.len() + body_size),
actual: bytes.len()
})
}
}
}
tuple_impls!($($_t: $_elem),*);
}
}
tuple_impls! {
A: a,
B: b,
C: c,
D: d,
E: e,
F: f,
G: g,
H: h,
I: i,
J: j,
K: k,
L: l
}
impl ByteEncodable for () {
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
Some(Size::from_usize(0))
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
Size::from_usize(0).encode::<Size>()
}
}
impl ByteDecodable for () {
fn decode<Size>(_: &[u8]) -> BVDecodeResult<()>
where
Size: BVSize + ByteDecodable,
{
Ok(())
}
}
impl ByteEncodable for bool {
fn get_size<Size>(&self) -> Option<Size>
where
Size: BVSize + ByteEncodable,
{
Some(Size::from_usize(1))
}
fn encode<Size>(&self) -> BVEncodeResult<Vec<u8>>
where
Size: BVSize + ByteEncodable,
{
Ok(match self {
true => vec![1u8],
false => vec![0u8],
})
}
}
impl ByteDecodable for bool {
fn decode<Size>(val: &[u8]) -> BVDecodeResult<bool>
where
Size: BVSize + ByteDecodable,
{
Ok(val[0] != 0u8)
}
}