From cffab13cfbd9830c87aadef1da568b5fa665283f Mon Sep 17 00:00:00 2001 From: Simon Pizonka Date: Wed, 19 Jun 2024 13:35:47 +0200 Subject: [PATCH] feat: add TryFrom for GethTrace for all inner variants (#933) * feat: add TryFrom for GethTrace for all inner variants * Use workspace version for thiserror * Fix clippy findings * Simplify error * Add functions for try_into_{tracer-variant} for GethTrace * Fix clippy findings * Update changelog * Typo * Fix clippy findings * Remove redundant TryFrom implementation and rename try_into method to match the returning type --- crates/rpc-types-trace/CHANGELOG.md | 3 + crates/rpc-types-trace/Cargo.toml | 1 + crates/rpc-types-trace/src/geth/mod.rs | 102 +++++++++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index 1afd9313b36..af51033a7e4 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/alloy-rs/alloy/compare/v0.1.1...HEAD) +- Add `try_into_{variant}()` for all inner `GethTrace` variants ([#929](https://github.com/alloy-rs/alloy/issues/929)) + + ## [0.1.1](https://github.com/alloy-rs/alloy/tree/v0.1.1) ### Features diff --git a/crates/rpc-types-trace/Cargo.toml b/crates/rpc-types-trace/Cargo.toml index bb66e4d6608..577584c4aed 100644 --- a/crates/rpc-types-trace/Cargo.toml +++ b/crates/rpc-types-trace/Cargo.toml @@ -25,6 +25,7 @@ alloy-serde.workspace = true serde.workspace = true serde_json.workspace = true +thiserror.workspace = true [dev-dependencies] alloy-primitives = { workspace = true, features = [ diff --git a/crates/rpc-types-trace/src/geth/mod.rs b/crates/rpc-types-trace/src/geth/mod.rs index ea71b8440da..17584518b0c 100644 --- a/crates/rpc-types-trace/src/geth/mod.rs +++ b/crates/rpc-types-trace/src/geth/mod.rs @@ -23,6 +23,11 @@ pub mod mux; pub mod noop; pub mod pre_state; +/// Error when the inner tracer from [GethTrace] is mismatching to the target tracer. +#[derive(Debug, thiserror::Error)] +#[error("unexpected tracer")] +pub struct UnexpectedTracerError(pub GethTrace); + /// Result type for geth style transaction trace pub type TraceResult = crate::common::TraceResult; @@ -123,6 +128,64 @@ pub enum GethTrace { JS(serde_json::Value), } +impl GethTrace { + /// Try to convert the inner tracer to [DefaultFrame] + pub fn try_into_default_frame(self) -> Result { + match self { + Self::Default(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + + /// Try to convert the inner tracer to [CallFrame] + pub fn try_into_call_frame(self) -> Result { + match self { + Self::CallTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + + /// Try to convert the inner tracer to [FourByteFrame] + pub fn try_into_four_byte_frame(self) -> Result { + match self { + Self::FourByteTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + + /// Try to convert the inner tracer to [PreStateFrame] + pub fn try_into_pre_state_frame(self) -> Result { + match self { + Self::PreStateTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + + /// Try to convert the inner tracer to [NoopFrame] + pub fn try_into_noop_frame(self) -> Result { + match self { + Self::NoopTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + + /// Try to convert the inner tracer to [MuxFrame] + pub fn try_into_mux_frame(self) -> Result { + match self { + Self::MuxTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + + /// Try to convert the inner tracer to [serde_json::Value] + pub fn try_into_json_value(self) -> Result { + match self { + Self::JS(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } +} + impl Default for GethTrace { fn default() -> Self { Self::Default(DefaultFrame::default()) @@ -659,4 +722,43 @@ mod tests { let val = serde_json::from_str::(s).unwrap(); similar_asserts::assert_eq!(val, de); } + + #[test] + fn test_geth_trace_into_tracer() { + let geth_trace = GethTrace::Default(DefaultFrame::default()); + let inner = geth_trace.try_into_default_frame(); + assert!(inner.is_ok()); + + let geth_trace = GethTrace::CallTracer(CallFrame::default()); + let inner = geth_trace.try_into_call_frame(); + assert!(inner.is_ok()); + + let geth_trace = GethTrace::FourByteTracer(FourByteFrame::default()); + let inner = geth_trace.try_into_four_byte_frame(); + assert!(inner.is_ok()); + + let geth_trace = GethTrace::PreStateTracer(PreStateFrame::Default(PreStateMode::default())); + let inner = geth_trace.try_into_pre_state_frame(); + assert!(inner.is_ok()); + + let geth_trace = GethTrace::NoopTracer(NoopFrame::default()); + let inner = geth_trace.try_into_noop_frame(); + assert!(inner.is_ok()); + + let geth_trace = GethTrace::MuxTracer(MuxFrame::default()); + let inner = geth_trace.try_into_mux_frame(); + assert!(inner.is_ok()); + + let geth_trace = GethTrace::JS(serde_json::Value::Null); + let inner = geth_trace.try_into_json_value(); + assert!(inner.is_ok()); + } + + #[test] + fn test_geth_trace_into_tracer_wrong_tracer() { + let geth_trace = GethTrace::Default(DefaultFrame::default()); + let inner = geth_trace.try_into_call_frame(); + assert!(inner.is_err()); + assert!(matches!(inner, Err(UnexpectedTracerError(_)))); + } }