//! Macros useful for work with types that implement `BinaryKey` and `BinaryValue` traits. /// Fast concatenation of byte arrays and/or keys that implements /// `BinaryKey` trait. /// /// ``` /// let prefix = vec![0_u8; 10]; /// let key = PublicKey::zero(); /// /// let _result = concat_keys!(prefix, key); /// ``` macro_rules! concat_keys { (@capacity $key:expr) => ( $key.size() ); (@capacity $key:expr, $($tail:expr),+) => ( BinaryKey::size($key) + concat_keys!(@capacity $($tail),+) ); ($($key:expr),+) => ({ let capacity = concat_keys!(@capacity $($key),+); let mut buf = vec![0; capacity]; let mut _pos = 0; $( _pos += BinaryKey::write($key, &mut buf[_pos.._pos + BinaryKey::size($key)]); )* buf }); } /// Implements `BinaryKey` trait for any type that implements `BinaryValue`. #[macro_export] macro_rules! impl_binary_key_for_binary_value { ($type:ty) => { impl matterdb::BinaryKey for $type { fn size(&self) -> usize { matterdb::BinaryValue::to_bytes(self).len() } fn write(&self, buffer: &mut [u8]) -> usize { let mut bytes = matterdb::BinaryValue::to_bytes(self); buffer.swap_with_slice(&mut bytes); bytes.len() } fn read(buffer: &[u8]) -> Self::Owned { // `unwrap` is safe because only this code uses for // serialize and deserialize these keys. ::from_bytes(buffer.into()).unwrap() } } }; } /// Hex conversions for the given `BinaryValue`. /// /// Implements `hex::FromHex` and `hex::ToHex` conversions for the given `BinaryValue` and uses them in /// the implementation of the following traits: /// /// `FromStr`, `Display`, `Serialize`, `Deserialize`. /// /// Pay attention that macro uses `serde_str` under the hood. #[macro_export] macro_rules! impl_serde_hex_for_binary_value { ($name:ident) => { impl hex::ToHex for $name { fn encode_hex>(&self) -> T { use $crate::BinaryValue; BinaryValue::to_bytes(self).encode_hex() } fn encode_hex_upper>(&self) -> T { use $crate::BinaryValue; BinaryValue::to_bytes(self).encode_hex_upper() } } impl hex::FromHex for $name { type Error = $crate::_reexports::Error; fn from_hex>(v: T) -> Result { use $crate::BinaryValue; let bytes = Vec::::from_hex(v)?; ::from_bytes(bytes.into()).map_err(From::from) } } impl std::fmt::Display for $name { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use hex::ToHex; write!(f, "{}", ::encode_hex::(self)) } } impl std::str::FromStr for $name { type Err = $crate::_reexports::Error; fn from_str(s: &str) -> Result { use hex::FromHex; ::from_hex(s) } } impl<'de> serde::Deserialize<'de> for $name { fn deserialize(deserializer: D) -> Result where D: serde::de::Deserializer<'de>, { serde_str::deserialize(deserializer) } } impl serde::Serialize for $name { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { serde_str::serialize(self, serializer) } } }; }