revm_inspector/
either.rs

1use crate::inspector::Inspector;
2use either::Either;
3use interpreter::{
4    CallInputs, CallOutcome, CreateInputs, CreateOutcome, Interpreter, InterpreterTypes,
5};
6use primitives::{Address, Log, U256};
7
8impl<CTX, INTR: InterpreterTypes, L, R> Inspector<CTX, INTR> for Either<L, R>
9where
10    L: Inspector<CTX, INTR>,
11    R: Inspector<CTX, INTR>,
12{
13    #[inline]
14    fn initialize_interp(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
15        match self {
16            Either::Left(inspector) => inspector.initialize_interp(interp, context),
17            Either::Right(inspector) => inspector.initialize_interp(interp, context),
18        }
19    }
20
21    #[inline]
22    fn step(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
23        match self {
24            Either::Left(inspector) => inspector.step(interp, context),
25            Either::Right(inspector) => inspector.step(interp, context),
26        }
27    }
28
29    #[inline]
30    fn step_end(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX) {
31        match self {
32            Either::Left(inspector) => inspector.step_end(interp, context),
33            Either::Right(inspector) => inspector.step_end(interp, context),
34        }
35    }
36
37    #[inline]
38    fn log(&mut self, context: &mut CTX, log: Log) {
39        match self {
40            Either::Left(inspector) => inspector.log(context, log),
41            Either::Right(inspector) => inspector.log(context, log),
42        }
43    }
44
45    #[inline]
46    fn log_full(&mut self, interp: &mut Interpreter<INTR>, context: &mut CTX, log: Log) {
47        match self {
48            Either::Left(inspector) => inspector.log_full(interp, context, log),
49            Either::Right(inspector) => inspector.log_full(interp, context, log),
50        }
51    }
52
53    #[inline]
54    fn call(&mut self, context: &mut CTX, inputs: &mut CallInputs) -> Option<CallOutcome> {
55        match self {
56            Either::Left(inspector) => inspector.call(context, inputs),
57            Either::Right(inspector) => inspector.call(context, inputs),
58        }
59    }
60
61    #[inline]
62    fn call_end(&mut self, context: &mut CTX, inputs: &CallInputs, outcome: &mut CallOutcome) {
63        match self {
64            Either::Left(inspector) => inspector.call_end(context, inputs, outcome),
65            Either::Right(inspector) => inspector.call_end(context, inputs, outcome),
66        }
67    }
68
69    #[inline]
70    fn create(&mut self, context: &mut CTX, inputs: &mut CreateInputs) -> Option<CreateOutcome> {
71        match self {
72            Either::Left(inspector) => inspector.create(context, inputs),
73            Either::Right(inspector) => inspector.create(context, inputs),
74        }
75    }
76
77    #[inline]
78    fn create_end(
79        &mut self,
80        context: &mut CTX,
81        inputs: &CreateInputs,
82        outcome: &mut CreateOutcome,
83    ) {
84        match self {
85            Either::Left(inspector) => inspector.create_end(context, inputs, outcome),
86            Either::Right(inspector) => inspector.create_end(context, inputs, outcome),
87        }
88    }
89
90    #[inline]
91    fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) {
92        match self {
93            Either::Left(inspector) => inspector.selfdestruct(contract, target, value),
94            Either::Right(inspector) => inspector.selfdestruct(contract, target, value),
95        }
96    }
97}
98
99#[cfg(test)]
100mod tests {
101    use super::*;
102    use crate::noop::NoOpInspector;
103    use interpreter::interpreter::EthInterpreter;
104
105    #[derive(Default)]
106    struct DummyInsp;
107
108    impl<CTX> Inspector<CTX, EthInterpreter> for DummyInsp {}
109
110    #[test]
111    fn test_either_inspector_type_check() {
112        // This test verifies that Either<NoOpInspector, NoOpInspector>
113        // implements the Inspector trait as required by the issue
114        fn _requires_inspector<T: Inspector<(), EthInterpreter>>(inspector: T) -> T {
115            inspector
116        }
117
118        let left_inspector = Either::<NoOpInspector, DummyInsp>::Left(NoOpInspector);
119        let right_inspector = Either::<NoOpInspector, DummyInsp>::Right(DummyInsp);
120
121        // These calls should compile successfully, proving that the Inspector trait is implemented
122        let _left = _requires_inspector(left_inspector);
123        let _right = _requires_inspector(right_inspector);
124    }
125}