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
Generated
+1806 -2
View File
File diff suppressed because it is too large Load Diff
+5
View File
@@ -16,6 +16,11 @@ rust-version = "1.85.0"
revive-differential-testing-format = { version = "0.1.0", path = "crates/format" }
anyhow = "1.0"
alloy-json-abi = "0.8.23"
alloy-genesis = "0.12.6"
alloy-primitives = { version = "0.8.23", features = ["serde"] }
alloy-serde = "0.12.6"
alloy-sol-types = "0.8.23"
semver = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["arbitrary_precision"] }
+5
View File
@@ -8,6 +8,11 @@ repository.workspace = true
rust-version.workspace = true
[dependencies]
alloy-json-abi = { workspace = true }
alloy-genesis = { workspace = true }
alloy-serde = { workspace = true }
alloy-primitives = { workspace = true }
alloy-sol-types = { workspace = true }
anyhow = { workspace = true }
semver = { workspace = true }
serde = { workspace = true, features = [ "derive" ] }
+8 -5
View File
@@ -1,9 +1,12 @@
use serde::Deserialize;
use serde::{Deserialize, de::Deserializer};
use crate::modes::Mode;
use crate::{input::Input, mode::Mode};
#[derive(Debug, Deserialize)]
#[derive(Debug, Default, Deserialize, Clone, Eq, PartialEq)]
pub struct Case {
#[serde(rename(deserialize = "modes"))]
pub modes: Vec<Mode>,
pub name: Option<String>,
pub comment: Option<String>,
pub modes: Option<Vec<Mode>>,
pub inputs: Vec<Input>,
pub expected: Vec<String>,
}
+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}"
)));
}
}
}
})
}
+3 -1
View File
@@ -1,4 +1,6 @@
//! The revive differential tests case format.
pub mod case;
pub mod modes;
pub mod input;
pub mod metadata;
pub mod mode;
+14
View File
@@ -0,0 +1,14 @@
use std::collections::BTreeMap;
use serde::Deserialize;
use crate::{case::Case, mode::Mode};
#[derive(Debug, Default, Deserialize, Clone, Eq, PartialEq)]
pub struct Metadata {
pub cases: Vec<Case>,
pub contracts: Option<BTreeMap<String, String>>,
pub libraries: Option<BTreeMap<String, BTreeMap<String, String>>>,
pub ignore: Option<bool>,
pub modes: Option<Vec<Mode>>,
}
+3 -3
View File
@@ -1,9 +1,9 @@
use revive_differential_testing_format::case::Case;
use revive_differential_testing_format::metadata::Metadata;
fn main() {
let example_def = include_str!("../../../test.json");
let case: Case = serde_json::from_str(example_def).unwrap();
let metadata: Metadata = serde_json::from_str(example_def).unwrap();
println!("{case:?}");
println!("{metadata:?}");
}