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 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 let _left = _requires_inspector(left_inspector);
117 let _right = _requires_inspector(right_inspector);
118 }
119}