1use crate::AbiParserError;
2use crate::ParameterType;
3
4pub struct Function {
10 pub inputs: Vec<FunctionParameter>,
11 pub outputs: Vec<FunctionParameter>,
12 pub state_mutability: Option<StateMutability>,
13 pub payable: Option<bool>,
14 pub constant: Option<bool>,
15}
16
17impl Function {
18 pub fn parse(raw_func: &serde_json::Value) -> Result<Self, AbiParserError> {
20 let inputs = Self::parse_parameters(&raw_func["inputs"])?;
21 let outputs = Self::parse_parameters(&raw_func["outputs"])?;
22 Ok(Self {
23 inputs,
24 outputs,
25 state_mutability: StateMutability::parse(raw_func),
26 payable: raw_func["payable"].as_bool(), constant: raw_func["constant"].as_bool(), })
29 }
30
31 fn parse_parameters(
37 raw_func: &serde_json::Value,
38 ) -> Result<Vec<FunctionParameter>, AbiParserError> {
39 match raw_func {
40 serde_json::Value::Array(parameters) => {
41 let mut result = Vec::new();
42 for parameter in parameters {
43 let p_type = parameter["type"].as_str().ok_or_else(|| {
44 AbiParserError::MissingData("Missing parameter type".to_owned())
45 })?;
46 let p_name = parameter["name"].as_str().ok_or_else(|| {
47 AbiParserError::MissingData("Missing parameter name".to_owned())
48 })?;
49 let parameter_type = ParameterType::parse(p_type)?;
50 result.push(FunctionParameter {
51 name: p_name.to_owned(),
52 parameter_type,
53 });
54 }
55 Ok(result)
56 }
57 _ => Err(AbiParserError::InvalidAbiEncoding(
58 "Function parameters are not given as an array".to_owned(),
59 )),
60 }
61 }
62}
63
64pub struct FunctionParameter {
69 pub name: String,
70 pub parameter_type: ParameterType,
71}
72
73#[derive(Copy, Clone, Debug, PartialEq)]
75pub enum StateMutability {
76 Pure,
77 View,
78 NonPayable,
79 Payable,
80}
81
82impl StateMutability {
83 pub fn parse(raw_func: &serde_json::Value) -> Option<Self> {
86 match raw_func["stateMutability"].as_str() {
87 Some("pure") => Some(StateMutability::Pure),
88 Some("view") => Some(StateMutability::View),
89 Some("nonpayable") => Some(StateMutability::NonPayable),
90 Some("payable") => Some(StateMutability::Payable),
91 _ => None,
92 }
93 }
94}
95
96#[cfg(test)]
97mod test {
98 use super::*;
99 use crate::ParameterType;
100
101 #[test]
102 fn parse_function() {
103 let json: serde_json::Value = serde_json::from_str(
104 r#"{
105 "constant": true,
106 "name": "stuff",
107 "inputs": [
108 {
109 "name": "_spender",
110 "type": "address"
111 },
112 {
113 "name": "",
114 "type": "bytes64"
115 }
116 ],
117 "outputs": [],
118 "payable": false,
119 "type": "function",
120 "stateMutability": "view"
121 }"#,
122 )
123 .unwrap();
124
125 let function = Function::parse(&json).unwrap();
126 assert_eq!(function.inputs.len(), 2);
127 assert_eq!(function.inputs[0].parameter_type, ParameterType::Address);
128 assert_eq!(function.inputs[0].name, "_spender");
129 assert_eq!(
130 function.inputs[1].parameter_type,
131 ParameterType::FixedBytes(64)
132 );
133 assert!(function.inputs[1].name.is_empty());
134 assert!(function.outputs.is_empty());
135 assert_eq!(function.constant, Some(true));
136 assert_eq!(function.payable, Some(false));
137 assert_eq!(function.state_mutability, Some(StateMutability::View));
138 }
139}