1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use crate::errors::Error;
use crate::utils::has_array_format;
use crate::Property;
pub struct FunctionSelector {
pub signature: String,
pub encoded_selector: String,
pub final_selector: Vec<u8>,
}
pub fn build_fn_selector(fn_name: &str, params: &[Property]) -> Result<String, Error> {
let fn_selector = fn_name.to_owned();
let mut result: String = format!("{}(", fn_selector);
for (idx, param) in params.iter().enumerate() {
result.push_str(&build_fn_selector_params(param));
if idx + 1 < params.len() {
result.push(',');
}
}
result.push(')');
Ok(result)
}
fn build_fn_selector_params(prop: &Property) -> String {
let mut result: String = String::new();
if prop.is_custom_type() {
if prop.is_struct_type() {
result.push_str("s(");
} else if prop.is_enum_type() {
result.push_str("e(");
} else if prop.has_custom_type_in_array() {
result.push_str("a[");
} else if prop.has_custom_type_in_tuple() {
result.push('(');
} else {
panic!("unexpected custom type");
}
for (idx, component) in prop
.components
.as_ref()
.expect("No components found")
.iter()
.enumerate()
{
result.push_str(&build_fn_selector_params(component));
if idx + 1 < prop.components.as_ref().unwrap().len() {
result.push(',');
}
}
if result.starts_with("a[") {
let array_type_field = prop.type_field.clone();
let mut array_length = array_type_field.split(';').collect::<Vec<&str>>()[1]
.trim()
.to_string();
array_length.pop();
let array_length = array_length.parse::<usize>().expect("Invalid array length");
result.push(';');
result.push_str(array_length.to_string().as_str());
result.push(']');
} else {
result.push(')');
}
} else {
let param_str_no_whitespace: String = prop
.type_field
.chars()
.filter(|c| !c.is_whitespace())
.collect();
if has_array_format(¶m_str_no_whitespace) {
let array = format!("{}{}", "a", param_str_no_whitespace);
result.push_str(array.as_str());
} else {
result.push_str(¶m_str_no_whitespace);
}
}
result
}