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, interp: &mut Interpreter<INTR>, context: &mut CTX, log: Log) {
39        match self {
40            Either::Left(inspector) => inspector.log(interp, context, log),
41            Either::Right(inspector) => inspector.log(interp, context, log),
42        }
43    }
44
45    #[inline]
46    fn call(&mut self, context: &mut CTX, inputs: &mut CallInputs) -> Option<CallOutcome> {
47        match self {
48            Either::Left(inspector) => inspector.call(context, inputs),
49            Either::Right(inspector) => inspector.call(context, inputs),
50        }
51    }
52
53    #[inline]
54    fn call_end(&mut self, context: &mut CTX, inputs: &CallInputs, outcome: &mut CallOutcome) {
55        match self {
56            Either::Left(inspector) => inspector.call_end(context, inputs, outcome),
57            Either::Right(inspector) => inspector.call_end(context, inputs, outcome),
58        }
59    }
60
61    #[inline]
62    fn create(&mut self, context: &mut CTX, inputs: &mut CreateInputs) -> Option<CreateOutcome> {
63        match self {
64            Either::Left(inspector) => inspector.create(context, inputs),
65            Either::Right(inspector) => inspector.create(context, inputs),
66        }
67    }
68
69    #[inline]
70    fn create_end(
71        &mut self,
72        context: &mut CTX,
73        inputs: &CreateInputs,
74        outcome: &mut CreateOutcome,
75    ) {
76        match self {
77            Either::Left(inspector) => inspector.create_end(context, inputs, outcome),
78            Either::Right(inspector) => inspector.create_end(context, inputs, outcome),
79        }
80    }
81
82    #[inline]
83    fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) {
84        match self {
85            Either::Left(inspector) => inspector.selfdestruct(contract, target, value),
86            Either::Right(inspector) => inspector.selfdestruct(contract, target, value),
87        }
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::*;
94    use crate::noop::NoOpInspector;
95    use interpreter::interpreter::EthInterpreter;
96
97    #[derive(Default)]
98    struct DummyInsp;
99
100    impl<CTX> Inspector<CTX, EthInterpreter> for DummyInsp {}
101
102    #[test]
103    fn test_either_inspector_type_check() {
104        use interpreter::interpreter::EthInterpreter;
105
106        // This test verifies that Either<NoOpInspector, NoOpInspector>
107        // implements the Inspector trait as required by the issue
108        fn _requires_inspector<T: Inspector<(), EthInterpreter>>(inspector: T) -> T {
109            inspector
110        }
111
112        let left_inspector = Either::<NoOpInspector, DummyInsp>::Left(NoOpInspector);
113        let right_inspector = Either::<NoOpInspector, DummyInsp>::Right(DummyInsp);
114
115        // These calls should compile successfully, proving that the Inspector trait is implemented
116        let _left = _requires_inspector(left_inspector);
117        let _right = _requires_inspector(right_inspector);
118    }
119}