use bytes::Bytes;
use serde::{Deserialize, Serialize};
use crate::{Hashable, Merkleizable, cryptography::merkle_tree::MerkleBuilder};
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, std::hash::Hash)]
pub struct CallData(
#[serde(
serialize_with = "serialize_bytes_as_hex",
deserialize_with = "deserialize_bytes_as_hex"
)]
Bytes,
);
impl CallData {
pub fn new(data: Bytes) -> Self {
assert!(data.len() >= 4, "CallData must contain at least 4 bytes");
CallData(data)
}
pub fn as_slice(&self) -> &[u8] {
&self.0[..]
}
pub fn as_bytes(&self) -> &Bytes {
&self.0
}
pub fn empty() -> Self {
CallData(Bytes::from(vec![]))
}
pub fn to_hex_string(&self) -> String {
let mut result = String::with_capacity(self.0.len() * 2);
for &byte in self.0.iter() {
result.push_str(&format!("{byte:02x}"));
}
result
}
pub fn get_function_bytes(&self) -> [u8; 4] {
[self.0[0], self.0[1], self.0[2], self.0[3]]
}
pub fn get_body(&self) -> &[u8] {
&self.0[4..]
}
}
impl Merkleizable for CallData {
fn append_leaves(&self, builder: &mut MerkleBuilder) {
builder.add_field("calldata", self.0.hash_custom());
}
}
fn serialize_bytes_as_hex<S>(data: &Bytes, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_str(&hex::encode(data))
} else {
serializer.serialize_bytes(data)
}
}
fn deserialize_bytes_as_hex<'de, D>(deserializer: D) -> Result<Bytes, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
Ok(Bytes::from(
hex::decode(s).map_err(serde::de::Error::custom)?,
))
} else {
Ok(Bytes::deserialize(deserializer)?)
}
}