multiversx_sc_scenario/scenario/run_vm/
executor_config.rs1use multiversx_chain_vm::host::runtime::RuntimeWeakRef;
2use multiversx_chain_vm_executor::Executor;
3
4pub type CustomExecutorFn = fn(RuntimeWeakRef) -> Box<dyn Executor + Send + Sync>;
8
9#[derive(Default, Clone, Debug)]
10pub enum ExecutorConfig {
11 #[default]
13 Debugger,
14
15 Custom(CustomExecutorFn),
19
20 Experimental,
22
23 CompiledFeatureIfElse {
25 if_compiled: Box<ExecutorConfig>,
26 fallback: Box<ExecutorConfig>,
27 },
28
29 Composite(Vec<ExecutorConfig>),
32}
33
34impl ExecutorConfig {
35 pub fn then(self, next: Self) -> Self {
37 match self {
38 Self::Composite(mut list) => {
39 next.append_flattened_to_vec(&mut list);
40 Self::from_list(list)
41 }
42 _ => {
43 let mut list = Vec::new();
44 self.append_flattened_to_vec(&mut list);
45 next.append_flattened_to_vec(&mut list);
46 Self::from_list(list)
47 }
48 }
49 }
50
51 pub fn compiled_tests_if_else(if_compiled: Self, fallback: Self) -> Self {
53 Self::CompiledFeatureIfElse {
54 if_compiled: Box::new(if_compiled),
55 fallback: Box::new(fallback),
56 }
57 }
58
59 pub fn compiled_tests_or(fallback: Self) -> Self {
61 Self::compiled_tests_if_else(Self::Experimental, fallback)
62 }
63
64 pub fn full_suite() -> Self {
72 Self::compiled_tests_or(Self::Debugger.then(Self::Experimental))
73 }
74
75 fn from_list(mut list: Vec<ExecutorConfig>) -> Self {
76 if list.len() == 1 {
77 list.pop().unwrap()
78 } else {
79 Self::Composite(list)
80 }
81 }
82
83 fn append_flattened_to_vec(self, destination: &mut Vec<ExecutorConfig>) {
84 match self {
85 Self::Composite(list) => {
86 for item in list {
87 item.append_flattened_to_vec(destination);
88 }
89 }
90 _ => {
91 destination.push(self);
92 }
93 }
94 }
95}
96
97impl PartialEq for ExecutorConfig {
98 fn eq(&self, other: &Self) -> bool {
99 use ExecutorConfig::*;
100 match (self, other) {
101 (Debugger, Debugger) => true,
102 (Experimental, Experimental) => true,
103 (
104 CompiledFeatureIfElse {
105 if_compiled: a1,
106 fallback: b1,
107 },
108 CompiledFeatureIfElse {
109 if_compiled: a2,
110 fallback: b2,
111 },
112 ) => a1 == a2 && b1 == b2,
113 (Composite(v1), Composite(v2)) => v1 == v2,
114 (Custom(_), Custom(_)) => false,
116 _ => false,
117 }
118 }
119}
120
121impl Eq for ExecutorConfig {}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn executor_config_then_test() {
129 assert_eq!(
130 ExecutorConfig::Debugger.then(ExecutorConfig::Experimental),
131 ExecutorConfig::Composite(vec![ExecutorConfig::Debugger, ExecutorConfig::Experimental])
132 );
133
134 assert_eq!(
135 ExecutorConfig::Debugger
136 .then(ExecutorConfig::Experimental)
137 .then(ExecutorConfig::Debugger),
138 ExecutorConfig::Composite(vec![
139 ExecutorConfig::Debugger,
140 ExecutorConfig::Experimental,
141 ExecutorConfig::Debugger
142 ])
143 );
144 }
145
146 #[test]
147 fn executor_config_flatten_test() {
148 assert_eq!(
149 ExecutorConfig::Debugger
150 .then(ExecutorConfig::Experimental.then(ExecutorConfig::Debugger)),
151 ExecutorConfig::Composite(vec![
152 ExecutorConfig::Debugger,
153 ExecutorConfig::Experimental,
154 ExecutorConfig::Debugger
155 ])
156 );
157 }
158
159 #[test]
160 fn executor_config_full_suite() {
161 assert_eq!(
162 ExecutorConfig::full_suite(),
163 ExecutorConfig::CompiledFeatureIfElse {
164 if_compiled: Box::new(ExecutorConfig::Experimental),
165 fallback: Box::new(ExecutorConfig::Composite(vec![
166 ExecutorConfig::Debugger,
167 ExecutorConfig::Experimental,
168 ]))
169 }
170 );
171 }
172}