1#[cfg(feature = "serde")]
12use core::fmt;
13
14#[cfg(feature = "serde")]
15use serde::{
16 de::{Error, MapAccess, Visitor},
17 ser::SerializeMap,
18 Deserialize, Deserializer, Serialize, Serializer,
19};
20
21#[cfg(not(feature = "std"))]
22use crate::no_std_prelude::*;
23use crate::ParamType;
24#[cfg(feature = "serde")]
25use crate::{param_type::Writer, TupleParam};
26
27#[derive(Debug, Clone, PartialEq)]
29pub struct EventParam {
30 pub name: String,
32 pub kind: ParamType,
34 pub indexed: bool,
36}
37
38#[cfg(feature = "serde")]
39impl<'a> Deserialize<'a> for EventParam {
40 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
41 where
42 D: Deserializer<'a>,
43 {
44 deserializer.deserialize_any(EventParamVisitor)
45 }
46}
47
48#[cfg(feature = "serde")]
49struct EventParamVisitor;
50
51#[cfg(feature = "serde")]
52impl<'a> Visitor<'a> for EventParamVisitor {
53 type Value = EventParam;
54
55 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
56 write!(formatter, "a valid event parameter spec")
57 }
58
59 fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
60 where
61 V: MapAccess<'a>,
62 {
63 let mut name = None;
64 let mut kind = None;
65 let mut indexed = None;
66 let mut components = None;
67
68 while let Some(ref key) = map.next_key::<String>()? {
69 match key.as_ref() {
70 "name" => {
71 if name.is_some() {
72 return Err(Error::duplicate_field("name"));
73 }
74 name = Some(map.next_value()?);
75 }
76 "type" => {
77 if kind.is_some() {
78 return Err(Error::duplicate_field("kind"));
79 }
80 kind = Some(map.next_value()?);
81 }
82 "components" => {
83 if components.is_some() {
84 return Err(Error::duplicate_field("components"));
85 }
86 let component: Vec<TupleParam> = map.next_value()?;
87 components = Some(component)
88 }
89 "indexed" => {
90 if indexed.is_some() {
91 return Err(Error::duplicate_field("indexed"));
92 }
93 indexed = Some(map.next_value()?);
94 }
95 _ => {}
96 }
97 }
98 let name = name.ok_or_else(|| Error::missing_field("name"))?;
99 let mut kind = kind.ok_or_else(|| Error::missing_field("kind"))?;
100 crate::param::set_tuple_components(&mut kind, components)?;
101 let indexed = indexed.unwrap_or(false);
102 Ok(EventParam { name, kind, indexed })
103 }
104}
105
106#[cfg(feature = "serde")]
107impl Serialize for EventParam {
108 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
109 where
110 S: Serializer,
111 {
112 let mut map = serializer.serialize_map(None)?;
113 map.serialize_entry("name", &self.name)?;
114 map.serialize_entry("type", &Writer::write_for_abi(&self.kind, false))?;
115 map.serialize_entry("indexed", &self.indexed)?;
116 if let Some(inner_tuple) = crate::param::inner_tuple(&self.kind) {
117 map.serialize_key("components")?;
118 map.serialize_value(&crate::param::SerializeableParamVec(inner_tuple))?;
119 }
120 map.end()
121 }
122}
123
124#[cfg(all(test, feature = "serde"))]
125mod tests {
126 #[cfg(not(feature = "std"))]
127 use crate::no_std_prelude::*;
128 use crate::{tests::assert_json_eq, EventParam, ParamType};
129
130 #[test]
131 fn event_param_deserialization() {
132 let s = r#"{
133 "name": "foo",
134 "type": "address",
135 "indexed": true
136 }"#;
137
138 let deserialized: EventParam = serde_json::from_str(s).unwrap();
139
140 assert_eq!(deserialized, EventParam { name: "foo".to_owned(), kind: ParamType::Address, indexed: true });
141
142 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
143 }
144
145 #[test]
146 fn event_param_tuple_deserialization() {
147 let s = r#"{
148 "name": "foo",
149 "type": "tuple",
150 "indexed": true,
151 "components": [
152 {
153 "type": "uint48"
154 },
155 {
156 "type": "tuple",
157 "components": [
158 {
159 "type": "address"
160 }
161 ]
162 }
163 ]
164 }"#;
165
166 let deserialized: EventParam = serde_json::from_str(s).unwrap();
167
168 assert_eq!(
169 deserialized,
170 EventParam {
171 name: "foo".to_owned(),
172 kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
173 indexed: true,
174 }
175 );
176
177 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
178 }
179
180 #[test]
181 fn event_param_tuple_array_deserialization() {
182 let s = r#"{
183 "components": [
184 { "type": "uint256" },
185 { "type": "address" },
186 {
187 "components": [
188 { "type": "address" },
189 { "type": "address" }
190 ],
191 "type": "tuple"
192 },
193 { "type": "uint256" },
194 {
195 "components": [
196 {
197 "components": [
198 { "type": "address" },
199 { "type": "bytes" }
200 ],
201 "type": "tuple[]"
202 },
203 {
204 "components": [
205 { "type": "address" },
206 { "type": "uint256" }
207 ],
208 "type": "tuple[]"
209 },
210 { "type": "uint256" }
211 ],
212 "type": "tuple[]"
213 },
214 { "type": "uint256" }
215 ],
216 "indexed": false,
217 "name": "LogTaskSubmitted",
218 "type": "tuple"
219 }"#;
220
221 let deserialized: EventParam = serde_json::from_str(s).unwrap();
222
223 assert_eq!(
224 deserialized,
225 EventParam {
226 name: "LogTaskSubmitted".to_owned(),
227 kind: ParamType::Tuple(vec![
228 ParamType::Uint(256),
229 ParamType::Address,
230 ParamType::Tuple(vec![ParamType::Address, ParamType::Address]),
231 ParamType::Uint(256),
232 ParamType::Array(Box::new(ParamType::Tuple(vec![
233 ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address, ParamType::Bytes,]))),
234 ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address, ParamType::Uint(256)]))),
235 ParamType::Uint(256),
236 ]))),
237 ParamType::Uint(256),
238 ]),
239 indexed: false,
240 }
241 );
242
243 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
244 }
245}