use crate::de::{Deserialize, DeserializeError};
use crate::merkleization::{pack_bytes, Context, MerkleizationError, Merkleized, Root};
use crate::ser::{Serialize, SerializeError};
use crate::{SimpleSerialize, Sized};
use std::convert::TryInto;
use std::default::Default;
macro_rules! define_uint {
($uint:ty) => {
impl Sized for $uint {
fn is_variable_size() -> bool {
false
}
fn size_hint() -> usize {
(<$uint>::BITS / 8) as usize
}
}
impl Serialize for $uint {
fn serialize(&self, buffer: &mut Vec<u8>) -> Result<usize, SerializeError> {
buffer.extend_from_slice(&self.to_le_bytes());
Ok((<$uint>::BITS / 8) as usize)
}
}
impl Deserialize for $uint {
fn deserialize(encoding: &[u8]) -> Result<Self, DeserializeError> {
let byte_size = (<$uint>::BITS / 8) as usize;
if encoding.len() < byte_size {
return Err(DeserializeError::InputTooShort);
}
if encoding.len() > byte_size {
return Err(DeserializeError::ExtraInput);
}
let bytes = encoding[..byte_size]
.try_into()
.expect("slice has right length");
Ok(<$uint>::from_le_bytes(bytes))
}
}
impl Merkleized for $uint {
fn hash_tree_root(&self, _context: &Context) -> Result<Root, MerkleizationError> {
let mut root = vec![];
let _ = self.serialize(&mut root)?;
pack_bytes(&mut root);
Ok(root.as_slice().try_into().expect("is valid root"))
}
}
impl SimpleSerialize for $uint {
fn is_composite_type() -> bool {
false
}
}
};
}
define_uint!(u8);
define_uint!(u16);
define_uint!(u32);
define_uint!(u64);
define_uint!(u128);
define_uint!(usize);
#[repr(transparent)]
#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
pub struct U256(pub [u8; 32]);
impl Sized for U256 {
fn is_variable_size() -> bool {
false
}
fn size_hint() -> usize {
32
}
}
impl Serialize for U256 {
fn serialize(&self, buffer: &mut Vec<u8>) -> Result<usize, SerializeError> {
buffer.extend_from_slice(&self.0);
Ok(32)
}
}
impl Deserialize for U256 {
fn deserialize(encoding: &[u8]) -> Result<Self, DeserializeError> {
if encoding.len() < 32 {
return Err(DeserializeError::InputTooShort);
}
if encoding.len() > 32 {
return Err(DeserializeError::ExtraInput);
}
let bytes = encoding[..32].try_into().expect("slice has right length");
Ok(Self(bytes))
}
}
impl Merkleized for U256 {
fn hash_tree_root(&self, _context: &Context) -> Result<Root, MerkleizationError> {
Ok(Root::from_bytes(self.0))
}
}
impl SimpleSerialize for U256 {
fn is_composite_type() -> bool {
false
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::serialize;
#[test]
fn encode_uints() {
let tests = vec![(u8::default(), [0u8]), (2u8, [2u8]), (u8::MAX, [u8::MAX])];
for (value, expected) in tests {
let result = serialize(&value).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(2u16, [2u8, 0u8]),
(1337u16, [57u8, 5u8]),
(u16::MAX, [u8::MAX, u8::MAX]),
];
for (value, expected) in tests {
let result = serialize(&value).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(2u32, [2u8, 0u8, 0u8, 0u8]),
(1337u32, [57u8, 5u8, 0u8, 0u8]),
(u32::MAX, [u8::MAX, u8::MAX, u8::MAX, u8::MAX]),
];
for (value, expected) in tests {
let result = serialize(&value).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(2u64, [2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]),
(1337u64, [57u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]),
(u64::MAX, [u8::MAX; 8]),
];
for (value, expected) in tests {
let result = serialize(&value).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(
2u128,
[
2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
],
),
(
1337u128,
[
57u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
],
),
(u128::MAX, [u8::MAX; 16]),
];
for (value, expected) in tests {
let result = serialize(&value).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(U256([2u8; 32]), [2u8; 32]),
(U256([u8::MAX; 32]), [u8::MAX; 32]),
];
for (value, expected) in tests {
let result = serialize(&value).expect("can encode");
assert_eq!(result, expected);
}
}
#[test]
fn decode_uints() {
let tests = vec![(u8::default(), [0u8]), (2u8, [2u8]), (u8::MAX, [u8::MAX])];
for (expected, bytes) in tests {
let result = u8::deserialize(&bytes).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(2u16, [2u8, 0u8]),
(1337u16, [57u8, 5u8]),
(u16::MAX, [u8::MAX, u8::MAX]),
];
for (expected, bytes) in tests {
let result = u16::deserialize(&bytes).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(2u32, [2u8, 0u8, 0u8, 0u8]),
(1337u32, [57u8, 5u8, 0u8, 0u8]),
(u32::MAX, [u8::MAX, u8::MAX, u8::MAX, u8::MAX]),
];
for (expected, bytes) in tests {
let result = u32::deserialize(&bytes).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(2u64, [2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]),
(1337u64, [57u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]),
(u64::MAX, [u8::MAX; 8]),
];
for (expected, bytes) in tests {
let result = u64::deserialize(&bytes).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(
2u128,
[
2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
],
),
(
1337u128,
[
57u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
],
),
(u128::MAX, [u8::MAX; 16]),
];
for (expected, bytes) in tests {
let result = u128::deserialize(&bytes).expect("can encode");
assert_eq!(result, expected);
}
let tests = vec![
(U256([2u8; 32]), [2u8; 32]),
(U256([u8::MAX; 32]), [u8::MAX; 32]),
];
for (expected, bytes) in tests {
let result = U256::deserialize(&bytes).expect("can encode");
assert_eq!(result, expected);
}
}
}