Update ssz impl for fixed_len_vec

This commit is contained in:
Paul Hauner 2019-05-10 16:37:56 +10:00
parent 3cd112d42d
commit 1e2bf03d5e
No known key found for this signature in database
GPG Key ID: D362883A9218FCC6
2 changed files with 45 additions and 8 deletions

View File

@ -55,8 +55,26 @@ impl<T, N: Unsigned> ssz::Encodable for FixedLenVec<T, N>
where where
T: ssz::Encodable, T: ssz::Encodable,
{ {
fn ssz_append(&self, s: &mut ssz::SszStream) { fn is_ssz_fixed_len() -> bool {
s.append_vec(&self.vec) true
}
fn ssz_append(&self, buf: &mut Vec<u8>) {
if T::is_ssz_fixed_len() {
buf.reserve(T::ssz_fixed_len() * self.len());
for item in &self.vec {
item.ssz_append(buf);
}
} else {
let mut encoder = ssz::SszEncoder::list(buf, self.len() * ssz::BYTES_PER_LENGTH_OFFSET);
for item in &self.vec {
encoder.append(item);
}
encoder.finalize();
}
} }
} }
@ -64,7 +82,29 @@ impl<T, N: Unsigned> ssz::Decodable for FixedLenVec<T, N>
where where
T: ssz::Decodable + Default, T: ssz::Decodable + Default,
{ {
fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), ssz::DecodeError> { fn is_ssz_fixed_len() -> bool {
ssz::decode_ssz_list(bytes, index).and_then(|(vec, i)| Ok((vec.into(), i))) T::is_ssz_fixed_len()
}
fn ssz_fixed_len() -> usize {
if <Self as ssz::Decodable>::is_ssz_fixed_len() {
T::ssz_fixed_len() * N::to_usize()
} else {
ssz::BYTES_PER_LENGTH_OFFSET
}
}
fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> {
if bytes.len() == 0 {
Ok(FixedLenVec::from(vec![]))
} else if T::is_ssz_fixed_len() {
bytes
.chunks(T::ssz_fixed_len())
.map(|chunk| T::from_ssz_bytes(chunk))
.collect::<Result<Vec<T>, _>>()
.and_then(|vec| Ok(vec.into()))
} else {
ssz::decode_list_of_variable_length_items(bytes).and_then(|vec| Ok(vec.into()))
}
} }
} }

View File

@ -9,10 +9,7 @@ pub use typenum;
mod impls; mod impls;
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
pub struct FixedLenVec<T, N> pub struct FixedLenVec<T, N> {
where
N: Unsigned,
{
vec: Vec<T>, vec: Vec<T>,
_phantom: PhantomData<N>, _phantom: PhantomData<N>,
} }