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
use {ParamType, Error, ErrorKind};
pub struct Reader;
impl Reader {
pub fn read(name: &str) -> Result<ParamType, Error> {
if let Some(']') = name.chars().last() {
let num: String = name.chars()
.rev()
.skip(1)
.take_while(|c| *c != '[')
.collect::<String>()
.chars()
.rev()
.collect();
let count = name.chars().count();
if num.len() == 0 {
let subtype = try!(Reader::read(&name[..count - 2]));
return Ok(ParamType::Array(Box::new(subtype)));
} else {
let len = try!(usize::from_str_radix(&num, 10));
let subtype = try!(Reader::read(&name[..count - num.len() - 2]));
return Ok(ParamType::FixedArray(Box::new(subtype), len));
}
}
let result = match name {
"address" => ParamType::Address,
"bytes" => ParamType::Bytes,
"bool" => ParamType::Bool,
"string" => ParamType::String,
"int" => ParamType::Int(256),
"uint" => ParamType::Uint(256),
s if s.starts_with("int") => {
let len = try!(usize::from_str_radix(&s[3..], 10));
ParamType::Int(len)
},
s if s.starts_with("uint") => {
let len = try!(usize::from_str_radix(&s[4..], 10));
ParamType::Uint(len)
},
s if s.starts_with("bytes") => {
let len = try!(usize::from_str_radix(&s[5..], 10));
ParamType::FixedBytes(len)
},
_ => {
return Err(ErrorKind::InvalidName(name.to_owned()).into());
}
};
Ok(result)
}
}
#[cfg(test)]
mod tests {
use ParamType;
use super::Reader;
#[test]
fn test_read_param() {
assert_eq!(Reader::read("address").unwrap(), ParamType::Address);
assert_eq!(Reader::read("bytes").unwrap(), ParamType::Bytes);
assert_eq!(Reader::read("bytes32").unwrap(), ParamType::FixedBytes(32));
assert_eq!(Reader::read("bool").unwrap(), ParamType::Bool);
assert_eq!(Reader::read("string").unwrap(), ParamType::String);
assert_eq!(Reader::read("int").unwrap(), ParamType::Int(256));
assert_eq!(Reader::read("uint").unwrap(), ParamType::Uint(256));
assert_eq!(Reader::read("int32").unwrap(), ParamType::Int(32));
assert_eq!(Reader::read("uint32").unwrap(), ParamType::Uint(32));
}
#[test]
fn test_read_array_param() {
assert_eq!(Reader::read("address[]").unwrap(), ParamType::Array(Box::new(ParamType::Address)));
assert_eq!(Reader::read("uint[]").unwrap(), ParamType::Array(Box::new(ParamType::Uint(256))));
assert_eq!(Reader::read("bytes[]").unwrap(), ParamType::Array(Box::new(ParamType::Bytes)));
assert_eq!(Reader::read("bool[][]").unwrap(), ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Bool)))));
}
#[test]
fn test_read_fixed_array_param() {
assert_eq!(Reader::read("address[2]").unwrap(), ParamType::FixedArray(Box::new(ParamType::Address), 2));
assert_eq!(Reader::read("bool[17]").unwrap(), ParamType::FixedArray(Box::new(ParamType::Bool), 17));
assert_eq!(Reader::read("bytes[45][3]").unwrap(), ParamType::FixedArray(Box::new(ParamType::FixedArray(Box::new(ParamType::Bytes), 45)), 3));
}
#[test]
fn test_read_mixed_arrays() {
assert_eq!(Reader::read("bool[][3]").unwrap(), ParamType::FixedArray(Box::new(ParamType::Array(Box::new(ParamType::Bool))), 3));
assert_eq!(Reader::read("bool[3][]").unwrap(), ParamType::Array(Box::new(ParamType::FixedArray(Box::new(ParamType::Bool), 3))));
}
}