1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
pub trait Encode { fn encode(&self) -> Vec<u8>; fn required_len(&self) -> u64; fn is_dynamic() -> bool; } impl<T> Encode for &T where T: Encode, { fn encode(&self) -> Vec<u8> { T::encode(self) } fn required_len(&self) -> u64 { T::required_len(self) } fn is_dynamic() -> bool { T::is_dynamic() } } impl<T> Encode for Vec<T> where T: Encode, { fn encode(&self) -> Vec<u8> { let len = self.required_len(); let mut buf = vec![0u8; len as usize]; buf[24..32].copy_from_slice(&(self.len() as u64).to_be_bytes()); let mut offset = self.len() * 32; for (index, bytes) in self.into_iter().map(Encode::encode).enumerate() { if T::is_dynamic() { buf[32 + index * 32 + 24..32 + (index + 1) * 32] .copy_from_slice(&(offset as u64).to_be_bytes()); buf[32 + offset..32 + offset + bytes.len()].copy_from_slice(&bytes); offset += bytes.len() } else { buf[32 + index * 32..32 + (index + 1) * 32].copy_from_slice(&bytes); } } buf } fn required_len(&self) -> u64 { self.iter().map(Encode::required_len).sum::<u64>() + if T::is_dynamic() { 32 * self.len() + 32 } else { 32 } as u64 } fn is_dynamic() -> bool { true } } impl<'a, T> Encode for &'a [T] where T: Encode, { fn encode(&self) -> Vec<u8> { let len = self.required_len(); let mut buf = vec![0u8; len as usize]; buf[24..32].copy_from_slice(&(self.len() as u64).to_be_bytes()); let mut offset = self.len() * 32; for (index, bytes) in (*self).into_iter().map(Encode::encode).enumerate() { if T::is_dynamic() { buf[32 + index * 32 + 24..32 + (index + 1) * 32] .copy_from_slice(&(offset as u64).to_be_bytes()); buf[32 + offset..32 + offset + bytes.len()].copy_from_slice(&bytes); offset += bytes.len() } else { buf[32 + index * 32..32 + (index + 1) * 32].copy_from_slice(&bytes); } } buf } fn required_len(&self) -> u64 { self.iter().map(Encode::required_len).sum::<u64>() + if T::is_dynamic() { 32 * self.len() + 32 } else { 32 } as u64 } fn is_dynamic() -> bool { true } }