From 29ad64fbd1505c3e2f025669bee062ed67590aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thoralf=20M=C3=BCller?= Date: Mon, 15 Jan 2024 20:14:10 +0100 Subject: [PATCH] Derive packable again --- .../types/block/output/feature/metadata.rs | 79 +++---------------- 1 file changed, 10 insertions(+), 69 deletions(-) diff --git a/sdk/src/types/block/output/feature/metadata.rs b/sdk/src/types/block/output/feature/metadata.rs index 08caf39002..0e40a738dd 100644 --- a/sdk/src/types/block/output/feature/metadata.rs +++ b/sdk/src/types/block/output/feature/metadata.rs @@ -10,11 +10,8 @@ use core::ops::{Deref, RangeInclusive}; use packable::{ bounded::{BoundedU16, BoundedU8}, - error::{UnpackError, UnpackErrorExt}, - packer::Packer, prefix::{BTreeMapPrefix, BoxedSlicePrefix}, - unpacker::Unpacker, - Packable, PackableExt, + PackableExt, }; use crate::types::block::{output::StorageScore, protocol::WorkScore, Error}; @@ -35,12 +32,19 @@ type MetadataBTreeMap = BTreeMap, BoxedSlicePrefix>; /// Defines metadata, arbitrary binary data, that will be stored in the output. -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, packable::Packable)] +#[packable(unpack_error = Error, with = |err| Error::InvalidMetadataFeature(err.to_string()))] pub struct MetadataFeature( // Binary data. - pub(crate) MetadataBTreeMapPrefix, + #[packable(verify_with = verify_packable)] pub(crate) MetadataBTreeMapPrefix, ); +fn verify_packable(map: &MetadataBTreeMapPrefix) -> Result<(), Error> { + verify_keys_packable::(map)?; + verify_length_packable::(map)?; + Ok(()) +} + fn verify_keys_packable(map: &MetadataBTreeMapPrefix) -> Result<(), Error> { if VERIFY { for key in map.keys() { @@ -93,69 +97,6 @@ impl StorageScore for MetadataFeature {} impl WorkScore for MetadataFeature {} -impl Packable for MetadataFeature { - type UnpackError = Error; - type UnpackVisitor = (); - - fn pack(&self, packer: &mut P) -> Result<(), P::Error> { - (self.0.len() as u16).pack(packer)?; - - for (k, v) in self.0.iter() { - k.pack(packer)?; - v.pack(packer)?; - } - - Ok(()) - } - - fn unpack( - unpacker: &mut U, - visitor: &Self::UnpackVisitor, - ) -> Result> { - let len = u16::unpack::<_, VERIFY>(unpacker, &()).coerce()?; - - let mut map = MetadataBTreeMap::new(); - - for _ in 0..len { - let key = BoxedSlicePrefix::::unpack::<_, VERIFY>(unpacker, visitor) - .map_err(|_| Error::InvalidMetadataFeature("invalid key".to_string())) - .map_err(UnpackError::Packable)?; - - if let Some((last, _)) = map.last_key_value() { - match last.cmp(&key) { - core::cmp::Ordering::Equal => { - return Err(UnpackError::Packable(Error::InvalidMetadataFeature( - "duplicated key".to_string(), - ))); - } - core::cmp::Ordering::Greater => { - return Err(UnpackError::Packable(Error::InvalidMetadataFeature( - "unordered map".to_string(), - ))); - } - core::cmp::Ordering::Less => (), - } - } - - let value = BoxedSlicePrefix::::unpack::<_, VERIFY>(unpacker, visitor) - .map_err(|_| Error::InvalidMetadataFeature("invalid value".to_string())) - .map_err(UnpackError::Packable)?; - - map.insert(key, value); - } - - let r: MetadataBTreeMapPrefix = map - .try_into() - .map_err(|_| Error::InvalidMetadataFeature("invalid metadata feature".to_string())) - .map_err(UnpackError::Packable)?; - - verify_keys_packable::(&r).map_err(UnpackError::Packable)?; - verify_length_packable::(&r).map_err(UnpackError::Packable)?; - - Ok(Self(r)) - } -} - impl TryFrom, Vec)>> for MetadataFeature { type Error = Error;