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 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 let _left = _requires_inspector(left_inspector);
123 let _right = _requires_inspector(right_inspector);
124 }
125}