ethabi_fork_ethcontract/
tuple_param.rs1use crate::ParamType;
12use serde::{
13 de::{Error, MapAccess, Visitor},
14 Deserialize, Deserializer,
15};
16use std::fmt;
17
18#[derive(Debug, Clone, PartialEq)]
20pub struct TupleParam {
21 pub name: Option<String>,
23
24 pub kind: ParamType,
26}
27
28impl<'a> Deserialize<'a> for TupleParam {
29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30 where
31 D: Deserializer<'a>,
32 {
33 deserializer.deserialize_any(TupleParamVisitor)
34 }
35}
36
37struct TupleParamVisitor;
38
39impl<'a> Visitor<'a> for TupleParamVisitor {
40 type Value = TupleParam;
41
42 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
43 write!(formatter, "a valid tuple parameter spec")
44 }
45
46 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
47 where
48 A: MapAccess<'a>,
49 {
50 let mut name = None;
51 let mut kind = None;
52 let mut components = None;
53
54 while let Some(ref key) = map.next_key::<String>()? {
55 match key.as_ref() {
56 "name" => {
57 if name.is_some() {
58 return Err(Error::duplicate_field("name"));
59 }
60 name = Some(map.next_value()?);
61 }
62 "type" => {
63 if kind.is_some() {
64 return Err(Error::duplicate_field("type"));
65 }
66 kind = Some(map.next_value()?);
67 }
68 "components" => {
69 if components.is_some() {
70 return Err(Error::duplicate_field("components"));
71 }
72 let component: Vec<TupleParam> = map.next_value()?;
73 components = Some(component)
74 }
75 _ => {}
76 }
77 }
78
79 let mut kind = kind.ok_or_else(|| Error::missing_field("kind"))?;
80 crate::param::set_tuple_components(&mut kind, components)?;
81 Ok(TupleParam { name, kind })
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use crate::{ParamType, TupleParam};
88
89 #[test]
90 fn tuple_param_deserialization() {
91 let s = r#"[{
92 "name": "foo",
93 "type": "address"
94 },{
95 "name": "bar",
96 "type": "address"
97 },{
98 "name": "baz",
99 "type": "address"
100 },{
101 "type": "bool"
102 }
103 ]"#;
104
105 let deserialized: Vec<TupleParam> = serde_json::from_str(s).unwrap();
106
107 assert_eq!(
108 deserialized,
109 vec![
110 TupleParam { name: Some(String::from("foo")), kind: ParamType::Address },
111 TupleParam { name: Some(String::from("bar")), kind: ParamType::Address },
112 TupleParam { name: Some(String::from("baz")), kind: ParamType::Address },
113 TupleParam { name: None, kind: ParamType::Bool },
114 ]
115 );
116 }
117}