ssz: implement Encode and Decode for tuples
This commit is contained in:
parent
73c4171b52
commit
44ed3228b9
@ -41,6 +41,153 @@ impl_decodable_for_uint!(usize, 32);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl_decodable_for_uint!(usize, 64);
|
||||
|
||||
macro_rules! impl_decode_for_tuples {
|
||||
($(
|
||||
$Tuple:ident {
|
||||
$(($idx:tt) -> $T:ident)+
|
||||
}
|
||||
)+) => {
|
||||
$(
|
||||
impl<$($T: Decode),+> Decode for ($($T,)+) {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
$(
|
||||
<$T as Decode>::is_ssz_fixed_len() &&
|
||||
)*
|
||||
true
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
if <Self as Decode>::is_ssz_fixed_len() {
|
||||
$(
|
||||
<$T as Decode>::ssz_fixed_len() +
|
||||
)*
|
||||
0
|
||||
} else {
|
||||
BYTES_PER_LENGTH_OFFSET
|
||||
}
|
||||
}
|
||||
|
||||
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
let mut builder = SszDecoderBuilder::new(bytes);
|
||||
|
||||
$(
|
||||
builder.register_type::<$T>()?;
|
||||
)*
|
||||
|
||||
let mut decoder = builder.build()?;
|
||||
|
||||
Ok(($(
|
||||
decoder.decode_next::<$T>()?,
|
||||
)*
|
||||
))
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_decode_for_tuples! {
|
||||
Tuple2 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
}
|
||||
Tuple3 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
}
|
||||
Tuple4 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
}
|
||||
Tuple5 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
}
|
||||
Tuple6 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
}
|
||||
Tuple7 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
}
|
||||
Tuple8 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
}
|
||||
Tuple9 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
}
|
||||
Tuple10 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
(9) -> J
|
||||
}
|
||||
Tuple11 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
(9) -> J
|
||||
(10) -> K
|
||||
}
|
||||
Tuple12 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
(9) -> J
|
||||
(10) -> K
|
||||
(11) -> L
|
||||
}
|
||||
}
|
||||
|
||||
impl Decode for bool {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
true
|
||||
@ -520,4 +667,15 @@ mod tests {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple() {
|
||||
assert_eq!(<(u16, u16)>::from_ssz_bytes(&[0, 0, 0, 0]), Ok((0, 0)));
|
||||
assert_eq!(<(u16, u16)>::from_ssz_bytes(&[16, 0, 17, 0]), Ok((16, 17)));
|
||||
assert_eq!(<(u16, u16)>::from_ssz_bytes(&[0, 1, 2, 0]), Ok((256, 2)));
|
||||
assert_eq!(
|
||||
<(u16, u16)>::from_ssz_bytes(&[255, 255, 0, 0]),
|
||||
Ok((65535, 0))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,154 @@ impl_encodable_for_uint!(usize, 32);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl_encodable_for_uint!(usize, 64);
|
||||
|
||||
// Based on the `tuple_impls` macro from the standard library.
|
||||
macro_rules! impl_encode_for_tuples {
|
||||
($(
|
||||
$Tuple:ident {
|
||||
$(($idx:tt) -> $T:ident)+
|
||||
}
|
||||
)+) => {
|
||||
$(
|
||||
impl<$($T: Encode),+> Encode for ($($T,)+) {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
$(
|
||||
<$T as Encode>::is_ssz_fixed_len() &&
|
||||
)*
|
||||
true
|
||||
}
|
||||
|
||||
fn ssz_fixed_len() -> usize {
|
||||
if <Self as Encode>::is_ssz_fixed_len() {
|
||||
$(
|
||||
<$T as Encode>::ssz_fixed_len() +
|
||||
)*
|
||||
0
|
||||
} else {
|
||||
BYTES_PER_LENGTH_OFFSET
|
||||
}
|
||||
}
|
||||
|
||||
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||
let offset = $(
|
||||
<$T as Encode>::ssz_fixed_len() +
|
||||
)*
|
||||
0;
|
||||
|
||||
let mut encoder = SszEncoder::container(buf, offset);
|
||||
|
||||
$(
|
||||
encoder.append(&self.$idx);
|
||||
)*
|
||||
|
||||
encoder.finalize();
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_encode_for_tuples! {
|
||||
Tuple2 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
}
|
||||
Tuple3 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
}
|
||||
Tuple4 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
}
|
||||
Tuple5 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
}
|
||||
Tuple6 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
}
|
||||
Tuple7 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
}
|
||||
Tuple8 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
}
|
||||
Tuple9 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
}
|
||||
Tuple10 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
(9) -> J
|
||||
}
|
||||
Tuple11 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
(9) -> J
|
||||
(10) -> K
|
||||
}
|
||||
Tuple12 {
|
||||
(0) -> A
|
||||
(1) -> B
|
||||
(2) -> C
|
||||
(3) -> D
|
||||
(4) -> E
|
||||
(5) -> F
|
||||
(6) -> G
|
||||
(7) -> H
|
||||
(8) -> I
|
||||
(9) -> J
|
||||
(10) -> K
|
||||
(11) -> L
|
||||
}
|
||||
}
|
||||
|
||||
/// The SSZ "union" type.
|
||||
impl<T: Encode> Encode for Option<T> {
|
||||
fn is_ssz_fixed_len() -> bool {
|
||||
@ -292,4 +440,11 @@ mod tests {
|
||||
assert_eq!([1, 0, 0, 0].as_ssz_bytes(), vec![1, 0, 0, 0]);
|
||||
assert_eq!([1, 2, 3, 4].as_ssz_bytes(), vec![1, 2, 3, 4]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple() {
|
||||
assert_eq!((10u8, 11u8).as_ssz_bytes(), vec![10, 11]);
|
||||
assert_eq!((10u32, 11u8).as_ssz_bytes(), vec![10, 0, 0, 0, 11]);
|
||||
assert_eq!((10u8, 11u8, 12u8).as_ssz_bytes(), vec![10, 11, 12]);
|
||||
}
|
||||
}
|
||||
|
@ -346,4 +346,34 @@ mod round_trip {
|
||||
|
||||
round_trip(vec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_u8_u16() {
|
||||
let vec: Vec<(u8, u16)> = vec![
|
||||
(0, 0),
|
||||
(0, 1),
|
||||
(1, 0),
|
||||
(u8::max_value(), u16::max_value()),
|
||||
(0, u16::max_value()),
|
||||
(u8::max_value(), 0),
|
||||
(42, 12301),
|
||||
];
|
||||
|
||||
round_trip(vec);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_vec_vec() {
|
||||
let vec: Vec<(u64, Vec<u8>, Vec<Vec<u16>>)> = vec![
|
||||
(0, vec![], vec![vec![]]),
|
||||
(99, vec![101], vec![vec![], vec![]]),
|
||||
(
|
||||
42,
|
||||
vec![12, 13, 14],
|
||||
vec![vec![99, 98, 97, 96], vec![42, 44, 46, 48, 50]],
|
||||
),
|
||||
];
|
||||
|
||||
round_trip(vec);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user