ethabi/
event_param.rs

1// Copyright 2015-2020 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Event param specification.
10
11#[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/// Event param specification.
28#[derive(Debug, Clone, PartialEq)]
29pub struct EventParam {
30	/// Param name.
31	pub name: String,
32	/// Param type.
33	pub kind: ParamType,
34	/// Indexed flag. If true, param is used to build block bloom.
35	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}