raiden_primitives/
deserializers.rs1#![warn(clippy::missing_docs_in_private_items)]
2
3use std::{
4 fmt,
5 str::FromStr,
6};
7
8use serde::{
9 de::{
10 Error,
11 Visitor,
12 },
13 Deserialize,
14 Deserializer,
15};
16use web3::types::{
17 H256,
18 U256,
19};
20
21use crate::types::{
22 ChainID,
23 Signature,
24 U64,
25};
26
27pub fn u256_from_u64<'de, D>(deserializer: D) -> Result<U256, D::Error>
29where
30 D: Deserializer<'de>,
31{
32 let buf = u64::deserialize(deserializer)?;
33 Ok(U256::from(buf))
34}
35
36pub fn u256_from_str<'de, D>(deserializer: D) -> Result<U256, D::Error>
38where
39 D: Deserializer<'de>,
40{
41 let binding = serde_json::Value::deserialize(deserializer)?;
42 if let Some(value) = binding.as_u64() {
43 return Ok(U256::from(value))
44 }
45 let v = binding.as_str().ok_or_else(|| D::Error::custom("Could not parse U256"))?;
46 U256::from_dec_str(v).map_err(|_| D::Error::custom("Invalid U256"))
47}
48
49pub fn u256_from_optional_str<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
51where
52 D: Deserializer<'de>,
53{
54 let binding = serde_json::Value::deserialize(deserializer)?;
55 if let Some(value) = binding.as_u64() {
56 return Ok(Some(U256::from(value)))
57 }
58 let v = binding.as_str().ok_or_else(|| D::Error::custom("Could not parse U256"))?;
59 Ok(Some(U256::from_dec_str(v).map_err(|_| D::Error::custom("Invalid U256"))?))
60}
61
62pub fn u64_from_str<'de, D>(deserializer: D) -> Result<u64, D::Error>
64where
65 D: Deserializer<'de>,
66{
67 let value = serde_json::Value::deserialize(deserializer)?;
68 let v = match value.as_u64() {
69 Some(v) => v,
70 None => value
71 .as_str()
72 .and_then(|s| s.parse().ok())
73 .ok_or_else(|| D::Error::custom("non-integer"))?,
74 };
75 Ok(v)
76}
77
78pub fn h256_from_str<'de, D>(deserializer: D) -> Result<H256, D::Error>
80where
81 D: Deserializer<'de>,
82{
83 let binding = serde_json::Value::deserialize(deserializer)?;
84 let str_value = binding.as_str().ok_or_else(|| D::Error::custom("Could not parse H256"))?;
85 let hex_value = hex::decode(str_value.trim_start_matches("0x"))
86 .map_err(|e| D::Error::custom(format!("Could not decode hex: {:?}", e)))?;
87 Ok(H256::from_slice(&hex_value))
88}
89
90pub fn signature_from_str<'de, D>(deserializer: D) -> Result<Signature, D::Error>
92where
93 D: Deserializer<'de>,
94{
95 let v = serde_json::Value::deserialize(deserializer)?;
96 let v = v
97 .as_str()
98 .ok_or_else(|| D::Error::custom("Invalid signature"))?
99 .trim_start_matches("0x");
100 Ok(Signature::from(hex::decode(v).map_err(|_| D::Error::custom("Invalid signature"))?))
101}
102
103impl<'de> Deserialize<'de> for ChainID {
104 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
105 where
106 D: Deserializer<'de>,
107 {
108 struct IdVisitor;
110
111 impl<'de> Visitor<'de> for IdVisitor {
112 type Value = ChainID;
113
114 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 f.write_str("Chain ID as a number or string")
116 }
117
118 fn visit_u64<E>(self, id: u64) -> Result<Self::Value, E>
119 where
120 E: Error,
121 {
122 Ok(id.into())
123 }
124
125 fn visit_str<E>(self, id: &str) -> Result<Self::Value, E>
126 where
127 E: Error,
128 {
129 ChainID::from_str(id)
130 .map_err(|_| Error::custom("Could not parse ChainID from string"))
131 }
132 }
133
134 deserializer.deserialize_any(IdVisitor)
135 }
136}
137
138impl<'de> Deserialize<'de> for U64 {
139 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
140 where
141 D: Deserializer<'de>,
142 {
143 struct NumVisitor;
145
146 impl<'de> Visitor<'de> for NumVisitor {
147 type Value = U64;
148
149 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 f.write_str("U64 as a number or string")
151 }
152
153 fn visit_u64<E>(self, num: u64) -> Result<Self::Value, E>
154 where
155 E: Error,
156 {
157 Ok(U64::from(num))
158 }
159
160 fn visit_str<E>(self, num: &str) -> Result<Self::Value, E>
161 where
162 E: Error,
163 {
164 U64::from_str(num).map_err(|_| Error::custom("Could not parse U64 from string"))
165 }
166 }
167
168 deserializer.deserialize_any(NumVisitor)
169 }
170}