Skip to content

Commit

Permalink
const generic impls for [T; N] and SmallVec<[T; N]> (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
dknopik authored Feb 4, 2025
1 parent 784208e commit d6819f6
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 99 deletions.
104 changes: 50 additions & 54 deletions ssz/src/decode/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,71 +395,67 @@ impl Decode for U128 {
}
}

macro_rules! impl_decodable_for_u8_array {
($len: expr) => {
impl Decode for [u8; $len] {
fn is_ssz_fixed_len() -> bool {
true
}
impl<const N: usize> Decode for [u8; N] {
fn is_ssz_fixed_len() -> bool {
true
}

fn ssz_fixed_len() -> usize {
$len
}
fn ssz_fixed_len() -> usize {
N
}

fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
let len = bytes.len();
let expected = <Self as Decode>::ssz_fixed_len();
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
let len = bytes.len();
let expected = <Self as Decode>::ssz_fixed_len();

if len != expected {
Err(DecodeError::InvalidByteLength { len, expected })
} else {
let mut array: [u8; $len] = [0; $len];
array.copy_from_slice(bytes);
if len != expected {
Err(DecodeError::InvalidByteLength { len, expected })
} else {
let mut array: [u8; N] = [0; N];
array.copy_from_slice(bytes);

Ok(array)
}
}
Ok(array)
}
};
}
}

impl_decodable_for_u8_array!(4);
impl_decodable_for_u8_array!(32);
impl_decodable_for_u8_array!(48);

macro_rules! impl_for_vec {
($type: ty, $max_len: expr) => {
impl<T: Decode> Decode for $type {
fn is_ssz_fixed_len() -> bool {
false
}
impl<T: Decode> Decode for Vec<T> {
fn is_ssz_fixed_len() -> bool {
false
}

fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
if bytes.is_empty() {
Ok(Self::from_iter(iter::empty()))
} else if T::is_ssz_fixed_len() {
bytes
.chunks(T::ssz_fixed_len())
.map(T::from_ssz_bytes)
.collect()
} else {
decode_list_of_variable_length_items(bytes, $max_len)
}
}
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
if bytes.is_empty() {
Ok(vec![])
} else if T::is_ssz_fixed_len() {
bytes
.chunks(T::ssz_fixed_len())
.map(T::from_ssz_bytes)
.collect()
} else {
decode_list_of_variable_length_items(bytes, None)
}
};
}
}

impl_for_vec!(Vec<T>, None);
impl_for_vec!(SmallVec<[T; 1]>, None);
impl_for_vec!(SmallVec<[T; 2]>, None);
impl_for_vec!(SmallVec<[T; 3]>, None);
impl_for_vec!(SmallVec<[T; 4]>, None);
impl_for_vec!(SmallVec<[T; 5]>, None);
impl_for_vec!(SmallVec<[T; 6]>, None);
impl_for_vec!(SmallVec<[T; 7]>, None);
impl_for_vec!(SmallVec<[T; 8]>, None);
impl_for_vec!(SmallVec<[T; 96]>, None);
impl<T: Decode, const N: usize> Decode for SmallVec<[T; N]> {
fn is_ssz_fixed_len() -> bool {
false
}

fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
if bytes.is_empty() {
Ok(SmallVec::new())
} else if T::is_ssz_fixed_len() {
bytes
.chunks(T::ssz_fixed_len())
.map(T::from_ssz_bytes)
.collect()
} else {
decode_list_of_variable_length_items(bytes, None)
}
}
}

impl<K, V> Decode for BTreeMap<K, V>
where
Expand Down
81 changes: 36 additions & 45 deletions ssz/src/encode/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,34 +309,33 @@ where
}
}

macro_rules! impl_for_vec {
($type: ty) => {
impl<T: Encode> Encode for $type {
fn is_ssz_fixed_len() -> bool {
false
}
impl<T: Encode> Encode for Vec<T> {
fn is_ssz_fixed_len() -> bool {
false
}

fn ssz_bytes_len(&self) -> usize {
sequence_ssz_bytes_len(self.iter())
}
fn ssz_bytes_len(&self) -> usize {
sequence_ssz_bytes_len(self.iter())
}

fn ssz_append(&self, buf: &mut Vec<u8>) {
sequence_ssz_append(self.iter(), buf)
}
}
};
fn ssz_append(&self, buf: &mut Vec<u8>) {
sequence_ssz_append(self.iter(), buf)
}
}

impl_for_vec!(Vec<T>);
impl_for_vec!(SmallVec<[T; 1]>);
impl_for_vec!(SmallVec<[T; 2]>);
impl_for_vec!(SmallVec<[T; 3]>);
impl_for_vec!(SmallVec<[T; 4]>);
impl_for_vec!(SmallVec<[T; 5]>);
impl_for_vec!(SmallVec<[T; 6]>);
impl_for_vec!(SmallVec<[T; 7]>);
impl_for_vec!(SmallVec<[T; 8]>);
impl_for_vec!(SmallVec<[T; 96]>);
impl<T: Encode, const N: usize> Encode for SmallVec<[T; N]> {
fn is_ssz_fixed_len() -> bool {
false
}

fn ssz_bytes_len(&self) -> usize {
sequence_ssz_bytes_len(self.iter())
}

fn ssz_append(&self, buf: &mut Vec<u8>) {
sequence_ssz_append(self.iter(), buf)
}
}

impl<K, V> Encode for BTreeMap<K, V>
where
Expand Down Expand Up @@ -539,32 +538,24 @@ impl Encode for U128 {
}
}

macro_rules! impl_encodable_for_u8_array {
($len: expr) => {
impl Encode for [u8; $len] {
fn is_ssz_fixed_len() -> bool {
true
}
impl<const N: usize> Encode for [u8; N] {
fn is_ssz_fixed_len() -> bool {
true
}

fn ssz_fixed_len() -> usize {
$len
}
fn ssz_fixed_len() -> usize {
N
}

fn ssz_bytes_len(&self) -> usize {
$len
}
fn ssz_bytes_len(&self) -> usize {
N
}

fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(&self[..]);
}
}
};
fn ssz_append(&self, buf: &mut Vec<u8>) {
buf.extend_from_slice(&self[..]);
}
}

impl_encodable_for_u8_array!(4);
impl_encodable_for_u8_array!(32);
impl_encodable_for_u8_array!(48);

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit d6819f6

Please sign in to comment.