1#[cfg(feature = "serde")]
12use core::fmt;
13
14#[cfg(feature = "serde")]
15use serde::{
16 de::{Error, MapAccess, Visitor},
17 ser::{SerializeMap, SerializeSeq},
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 Param {
30 pub name: String,
32 pub kind: ParamType,
34 pub internal_type: Option<String>,
36}
37
38#[cfg(feature = "serde")]
39impl<'a> Deserialize<'a> for Param {
40 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
41 where
42 D: Deserializer<'a>,
43 {
44 deserializer.deserialize_any(ParamVisitor)
45 }
46}
47
48#[cfg(feature = "serde")]
49struct ParamVisitor;
50
51#[cfg(feature = "serde")]
52impl<'a> Visitor<'a> for ParamVisitor {
53 type Value = Param;
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 components = None;
66 let mut internal_type = 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 "internalType" => {
83 if internal_type.is_some() {
84 return Err(Error::duplicate_field("internalType"));
85 }
86 internal_type = Some(map.next_value()?);
87 }
88 "components" => {
89 if components.is_some() {
90 return Err(Error::duplicate_field("components"));
91 }
92 let component: Vec<TupleParam> = map.next_value()?;
93 components = Some(component)
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 set_tuple_components::<V::Error>(&mut kind, components)?;
101 Ok(Param { name, kind, internal_type })
102 }
103}
104
105#[cfg(feature = "serde")]
106impl Serialize for Param {
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: Serializer,
110 {
111 let mut map = serializer.serialize_map(None)?;
112 if let Some(ref internal_type) = self.internal_type {
113 map.serialize_entry("internalType", internal_type)?;
114 }
115 map.serialize_entry("name", &self.name)?;
116 map.serialize_entry("type", &Writer::write_for_abi(&self.kind, false))?;
117 if let Some(inner_tuple) = inner_tuple(&self.kind) {
118 map.serialize_key("components")?;
119 map.serialize_value(&SerializeableParamVec(inner_tuple))?;
120 }
121 map.end()
122 }
123}
124
125#[cfg(feature = "serde")]
126pub(crate) fn inner_tuple_mut(mut param: &mut ParamType) -> Option<&mut Vec<ParamType>> {
127 loop {
128 match param {
129 ParamType::Array(inner) => param = inner.as_mut(),
130 ParamType::FixedArray(inner, _) => param = inner.as_mut(),
131 ParamType::Tuple(inner) => return Some(inner),
132 _ => return None,
133 }
134 }
135}
136
137#[cfg(feature = "serde")]
138pub(crate) fn inner_tuple(mut param: &ParamType) -> Option<&Vec<ParamType>> {
139 loop {
140 match param {
141 ParamType::Array(inner) => param = inner.as_ref(),
142 ParamType::FixedArray(inner, _) => param = inner.as_ref(),
143 ParamType::Tuple(inner) => return Some(inner),
144 _ => return None,
145 }
146 }
147}
148
149#[cfg(feature = "serde")]
150pub(crate) fn set_tuple_components<Error: serde::de::Error>(
151 kind: &mut ParamType,
152 components: Option<Vec<TupleParam>>,
153) -> Result<(), Error> {
154 if let Some(inner_tuple_mut) = inner_tuple_mut(kind) {
155 let tuple_params = components.ok_or_else(|| Error::missing_field("components"))?;
156 inner_tuple_mut.extend(tuple_params.into_iter().map(|param| param.kind))
157 }
158 Ok(())
159}
160
161#[cfg(feature = "serde")]
162pub(crate) struct SerializeableParamVec<'a>(pub(crate) &'a [ParamType]);
163
164#[cfg(feature = "serde")]
165impl Serialize for SerializeableParamVec<'_> {
166 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
167 where
168 S: Serializer,
169 {
170 let mut seq = serializer.serialize_seq(None)?;
171 for param in self.0 {
172 seq.serialize_element(&SerializeableParam(param))?;
173 }
174 seq.end()
175 }
176}
177
178#[cfg(feature = "serde")]
179pub(crate) struct SerializeableParam<'a>(pub(crate) &'a ParamType);
180
181#[cfg(feature = "serde")]
182impl Serialize for SerializeableParam<'_> {
183 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
184 where
185 S: Serializer,
186 {
187 let mut map = serializer.serialize_map(None)?;
188 map.serialize_entry("type", &Writer::write_for_abi(self.0, false))?;
189 if let Some(inner_tuple) = inner_tuple(self.0) {
190 map.serialize_key("components")?;
191 map.serialize_value(&SerializeableParamVec(inner_tuple))?;
192 }
193 map.end()
194 }
195}
196
197#[cfg(all(test, feature = "serde"))]
198mod tests {
199 #[cfg(not(feature = "std"))]
200 use crate::no_std_prelude::*;
201 use crate::{
202 tests::{assert_json_eq, assert_ser_de},
203 Param, ParamType,
204 };
205
206 #[test]
207 fn param_simple() {
208 let s = r#"{
209 "name": "foo",
210 "type": "address"
211 }"#;
212
213 let deserialized: Param = serde_json::from_str(s).unwrap();
214
215 assert_eq!(deserialized, Param { name: "foo".to_owned(), kind: ParamType::Address, internal_type: None });
216
217 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
218 }
219
220 #[test]
221 fn param_simple_internal_type() {
222 let s = r#"{
223 "name": "foo",
224 "type": "address",
225 "internalType": "struct Verifier.Proof"
226 }"#;
227
228 let deserialized: Param = serde_json::from_str(s).unwrap();
229
230 assert_eq!(
231 deserialized,
232 Param {
233 name: "foo".to_owned(),
234 kind: ParamType::Address,
235 internal_type: Some("struct Verifier.Proof".to_string())
236 }
237 );
238
239 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
240 }
241
242 #[test]
243 fn param_tuple() {
244 let s = r#"{
245 "name": "foo",
246 "type": "tuple",
247 "components": [
248 {
249 "type": "uint48"
250 },
251 {
252 "type": "tuple",
253 "components": [
254 {
255 "type": "address"
256 }
257 ]
258 }
259 ]
260 }"#;
261
262 let deserialized: Param = serde_json::from_str(s).unwrap();
263
264 assert_eq!(
265 deserialized,
266 Param {
267 name: "foo".to_owned(),
268 kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
269 internal_type: None
270 }
271 );
272
273 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
274 }
275
276 #[test]
277 fn param_tuple_internal_type() {
278 let s = r#"{
279 "name": "foo",
280 "type": "tuple",
281 "internalType": "struct Pairing.G1Point[]",
282 "components": [
283 {
284 "type": "uint48"
285 },
286 {
287 "type": "tuple",
288 "components": [
289 {
290 "type": "address"
291 }
292 ]
293 }
294 ]
295 }"#;
296
297 let deserialized: Param = serde_json::from_str(s).unwrap();
298
299 assert_eq!(
300 deserialized,
301 Param {
302 name: "foo".to_owned(),
303 kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
304 internal_type: Some("struct Pairing.G1Point[]".to_string())
305 }
306 );
307
308 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
309 }
310
311 #[test]
312 fn param_tuple_named() {
313 let s = r#"{
314 "name": "foo",
315 "type": "tuple",
316 "components": [
317 {
318 "name": "amount",
319 "type": "uint48"
320 },
321 {
322 "name": "things",
323 "type": "tuple",
324 "components": [
325 {
326 "name": "baseTupleParam",
327 "type": "address"
328 }
329 ]
330 }
331 ]
332 }"#;
333
334 let deserialized: Param = serde_json::from_str(s).unwrap();
335
336 assert_eq!(
337 deserialized,
338 Param {
339 name: "foo".to_owned(),
340 kind: ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Tuple(vec![ParamType::Address])]),
341 internal_type: None
342 }
343 );
344
345 assert_ser_de(&deserialized);
346 }
347
348 #[test]
349 fn param_tuple_array() {
350 let s = r#"{
351 "name": "foo",
352 "type": "tuple[]",
353 "components": [
354 {
355 "type": "uint48"
356 },
357 {
358 "type": "address"
359 },
360 {
361 "type": "address"
362 }
363 ]
364 }"#;
365
366 let deserialized: Param = serde_json::from_str(s).unwrap();
367
368 assert_eq!(
369 deserialized,
370 Param {
371 name: "foo".to_owned(),
372 kind: ParamType::Array(Box::new(ParamType::Tuple(vec![
373 ParamType::Uint(48),
374 ParamType::Address,
375 ParamType::Address
376 ]))),
377 internal_type: None
378 }
379 );
380
381 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
382 }
383
384 #[test]
385 fn param_array_of_array_of_tuple() {
386 let s = r#"{
387 "name": "foo",
388 "type": "tuple[][]",
389 "components": [
390 {
391 "type": "uint8"
392 },
393 {
394 "type": "uint16"
395 }
396 ]
397 }"#;
398
399 let deserialized: Param = serde_json::from_str(s).unwrap();
400 assert_eq!(
401 deserialized,
402 Param {
403 name: "foo".to_owned(),
404 kind: ParamType::Array(Box::new(ParamType::Array(Box::new(ParamType::Tuple(vec![
405 ParamType::Uint(8),
406 ParamType::Uint(16),
407 ]))))),
408 internal_type: None
409 }
410 );
411
412 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
413 }
414
415 #[test]
416 fn param_tuple_fixed_array() {
417 let s = r#"{
418 "name": "foo",
419 "type": "tuple[2]",
420 "components": [
421 {
422 "type": "uint48"
423 },
424 {
425 "type": "address"
426 },
427 {
428 "type": "address"
429 }
430 ]
431 }"#;
432
433 let deserialized: Param = serde_json::from_str(s).unwrap();
434
435 assert_eq!(
436 deserialized,
437 Param {
438 name: "foo".to_owned(),
439 kind: ParamType::FixedArray(
440 Box::new(ParamType::Tuple(vec![ParamType::Uint(48), ParamType::Address, ParamType::Address])),
441 2
442 ),
443 internal_type: None
444 }
445 );
446
447 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
448 }
449
450 #[test]
451 fn param_tuple_with_nested_tuple_arrays() {
452 let s = r#"{
453 "name": "foo",
454 "type": "tuple",
455 "components": [
456 {
457 "type": "tuple[]",
458 "components": [
459 {
460 "type": "address"
461 }
462 ]
463 },
464 {
465 "type": "tuple[42]",
466 "components": [
467 {
468 "type": "address"
469 }
470 ]
471 }
472 ]
473 }"#;
474
475 let deserialized: Param = serde_json::from_str(s).unwrap();
476
477 assert_eq!(
478 deserialized,
479 Param {
480 name: "foo".to_owned(),
481 kind: ParamType::Tuple(vec![
482 ParamType::Array(Box::new(ParamType::Tuple(vec![ParamType::Address]))),
483 ParamType::FixedArray(Box::new(ParamType::Tuple(vec![ParamType::Address])), 42,)
484 ]),
485 internal_type: None
486 }
487 );
488
489 assert_json_eq(s, serde_json::to_string(&deserialized).unwrap().as_str());
490 }
491}