the metadata parser

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
Cyrill Leutwiler
2025-03-19 09:49:45 +01:00
parent 42d6f04f2d
commit d08d6fd66f
9 changed files with 1921 additions and 11 deletions
+77
View File
@@ -0,0 +1,77 @@
use alloy_json_abi::Function;
use alloy_primitives::U256;
use serde::{Deserialize, de::Deserializer};
/// Specify how the contract is called.
#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub enum Method {
/// Initiate a deploy transaction, calling contracts constructor.
///
/// Indicated by `#deployer`.
Deployer,
/// Does not calculate and insert a function selector.
///
/// Indicated by `#fallback`.
#[default]
Fallback,
/// Call the public function with this selector.
///
/// Calculates the selector if neither deployer or fallback matches.
Function([u8; 4]),
}
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct Input {
instance: String,
#[serde(deserialize_with = "deserialize_method")]
method: Method,
#[serde(deserialize_with = "deserialize_calldata")]
calldata: Vec<u8>,
expected: Option<Vec<String>>,
}
fn deserialize_calldata<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let calldata_strings: Vec<String> = Vec::deserialize(deserializer)?;
let mut result = Vec::with_capacity(calldata_strings.len() * 32);
for calldata_string in &calldata_strings {
match calldata_string.parse::<U256>() {
Ok(parsed) => result.extend_from_slice(&parsed.to_be_bytes::<32>()),
Err(error) => {
return Err(serde::de::Error::custom(&format!(
"parsing U256 {calldata_string} error: {error}"
)));
}
};
}
Ok(result)
}
fn deserialize_method<'de, D>(deserializer: D) -> Result<Method, D::Error>
where
D: Deserializer<'de>,
{
Ok(match String::deserialize(deserializer)?.as_str() {
"#deployer" => Method::Deployer,
"#fallback" => Method::Fallback,
signature => {
let signature = if signature.ends_with(')') {
signature.to_string()
} else {
format!("{signature}()")
};
match Function::parse(&signature) {
Ok(function) => Method::Function(function.selector().0),
Err(error) => {
return Err(serde::de::Error::custom(&format!(
"parsing function signature '{signature}' error: {error}"
)));
}
}
}
})
}