multiversx_chain_scenario_format/value_interpreter/
interpreter.rs1use crate::{interpret_trait::InterpreterContext, serde_raw::ValueSubTree};
2
3use super::{
4 file_loader::{load_file, MxscFileJson},
5 functions::*,
6 parse_num::*,
7 prefixes::*,
8};
9
10pub fn interpret_subtree(vst: &ValueSubTree, context: &InterpreterContext) -> Vec<u8> {
11 match vst {
12 ValueSubTree::Str(s) => interpret_string(s, context),
13 ValueSubTree::List(l) => {
14 let mut concat = Vec::<u8>::new();
15 for item in l.iter() {
16 concat.extend_from_slice(interpret_subtree(item, context).as_slice());
17 }
18 concat
19 }
20 ValueSubTree::Map(m) => {
21 let mut concat = Vec::<u8>::new();
22 for (_, value) in m.iter() {
23 concat.extend_from_slice(interpret_subtree(value, context).as_slice());
24 }
25 concat
26 }
27 }
28}
29
30pub fn interpret_string(s: &str, context: &InterpreterContext) -> Vec<u8> {
31 if s.is_empty() {
32 return Vec::new();
33 }
34
35 let split_parts: Vec<_> = s.split('|').collect();
37 if split_parts.len() > 1 {
38 let mut result = Vec::<u8>::new();
39 for part in split_parts.iter() {
40 result.extend_from_slice(interpret_string(part, context).as_slice());
41 }
42 return result;
43 }
44
45 if s == "true" {
46 return [1u8].to_vec();
47 }
48
49 if s == "false" {
50 return Vec::new();
51 }
52
53 for str_prefix in STR_PREFIXES.iter() {
54 if let Some(stripped) = s.strip_prefix(str_prefix) {
55 return stripped.as_bytes().to_vec();
56 }
57 }
58
59 if let Some(stripped) = s.strip_prefix(ADDR_PREFIX) {
60 return address_expression(stripped);
61 }
62
63 if let Some(stripped) = s.strip_prefix(SC_ADDR_PREFIX) {
64 return sc_address_expression(stripped, &context.vm_type);
65 }
66
67 if let Some(stripped) = s.strip_prefix(FILE_PREFIX) {
68 return load_file(stripped, context, |c| c);
69 }
70
71 if let Some(stripped) = s.strip_prefix(MXSC_PREFIX) {
72 return load_file(stripped, context, |content| {
73 let mxsc_json: MxscFileJson = serde_json::from_slice(&content).unwrap();
74 hex::decode(mxsc_json.code).expect("Could not decode contract code")
75 });
76 }
77
78 if let Some(stripped) = s.strip_prefix(KECCAK256_PREFIX) {
79 let arg = interpret_string(stripped, context);
80 return keccak256(arg.as_slice());
81 }
82
83 if let Some(stripped) = s.strip_prefix(BECH32_PREFIX) {
84 return bech32(stripped);
85 }
86
87 if let Some(stripped) = s.strip_prefix(NESTED_PREFIX) {
88 return parse_nested(stripped, context);
89 }
90
91 if let Some(fixed_width) = try_parse_fixed_width(s) {
92 return fixed_width;
93 }
94
95 parse_num(s)
96}
97
98fn parse_nested(s: &str, context: &InterpreterContext) -> Vec<u8> {
99 let parsed = interpret_string(s, context);
100 let encoded_length = (parsed.len() as u32).to_be_bytes();
101 [&encoded_length[..], &parsed[..]].concat()
102}