1use serde::de::{MapAccess, SeqAccess};
2use serde_json::Value;
3
4use crate::number::{try_parse_integer, try_parse_unsigned_integer};
5
6struct AleoDeserializer {
7 ast: Value,
8}
9
10impl AleoDeserializer {
11 fn new(input: &str) -> Self {
12 let ast = crate::parse_struct(input);
13 Self { ast: ast }
14 }
15
16 fn from_value(value: Value) -> Self {
17 Self { ast: value }
18 }
19}
20
21macro_rules! impl_deserialize_any {
22 ($($method:ident),*) => {
23 $(
24 fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
25 where
26 V: serde::de::Visitor<'de>,
27 {
28 self.deserialize_any(visitor)
29 }
30 )*
31 };
32}
33
34impl<'de> serde::Deserializer<'de> for AleoDeserializer {
35 type Error = serde_json::Error;
36
37 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
38 where
39 V: serde::de::Visitor<'de>,
40 {
41 match self.ast {
42 serde_json::Value::Null => visitor.visit_none(),
43 serde_json::Value::Bool(v) => visitor.visit_bool(v),
44 serde_json::Value::Number(number) => visitor.visit_i64(number.as_i64().unwrap()),
45 serde_json::Value::String(str) => {
46 if let Some((number, bitsize)) = try_parse_unsigned_integer(&str) {
47 match bitsize {
48 8 => visitor.visit_u8(number as u8),
49 16 => visitor.visit_u16(number as u16),
50 32 => visitor.visit_u32(number as u32),
51 64 => visitor.visit_u64(number as u64),
52 _ => visitor.visit_u128(number),
53 }
54 } else if let Some((number, bitsize)) = try_parse_integer(&str) {
55 match bitsize {
56 8 => visitor.visit_i8(number as i8),
57 16 => visitor.visit_i16(number as i16),
58 32 => visitor.visit_i32(number as i32),
59 64 => visitor.visit_i64(number as i64),
60 _ => visitor.visit_i128(number),
61 }
62 } else {
63 visitor.visit_str(&str)
64 }
65 }
66 serde_json::Value::Array(values) => {
67 struct JsonSeqAccess {
68 iter: Vec<Value>,
69 idx: usize,
70 }
71 impl<'de> SeqAccess<'de> for JsonSeqAccess {
72 type Error = serde_json::Error;
73 fn next_element_seed<T>(
74 &mut self,
75 seed: T,
76 ) -> Result<Option<T::Value>, Self::Error>
77 where
78 T: serde::de::DeserializeSeed<'de>,
79 {
80 if self.idx >= self.iter.len() {
81 return Ok(None);
82 }
83 let res = self
84 .iter
85 .get(self.idx)
86 .map(|v| seed.deserialize(AleoDeserializer::from_value(v.clone())))
87 .transpose();
88 self.idx += 1;
89 res
90 }
91 }
92 visitor.visit_seq(JsonSeqAccess {
93 iter: values,
94 idx: 0,
95 })
96 }
97 serde_json::Value::Object(map) => {
98 struct JsonMapAccess {
99 iter: std::vec::IntoIter<(String, Value)>,
100 value: Option<Value>,
101 }
102 impl<'de> MapAccess<'de> for JsonMapAccess {
103 type Error = serde_json::Error;
104 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
105 where
106 K: serde::de::DeserializeSeed<'de>,
107 {
108 if let Some((k, v)) = self.iter.next() {
109 self.value = Some(v);
110 seed.deserialize(Value::String(k)).map(Some)
111 } else {
112 Ok(None)
113 }
114 }
115 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
116 where
117 V: serde::de::DeserializeSeed<'de>,
118 {
119 let v = self
120 .value
121 .take()
122 .expect("value must be available after key");
123 let de = AleoDeserializer::from_value(v);
124 seed.deserialize(de)
125 }
126 }
127 let entries: Vec<(String, Value)> = map.into_iter().collect();
128 visitor.visit_map(JsonMapAccess {
129 iter: entries.into_iter(),
130 value: None,
131 })
132 }
133 }
134 }
135
136 impl_deserialize_any! {
137 deserialize_bool,
138 deserialize_i8,
139 deserialize_i16,
140 deserialize_i32,
141 deserialize_i64,
142 deserialize_i128,
143 deserialize_u8,
144 deserialize_u16,
145 deserialize_u32,
146 deserialize_u64,
147 deserialize_u128,
148 deserialize_f32,
149 deserialize_f64,
150 deserialize_char,
151 deserialize_str,
152 deserialize_string,
153 deserialize_bytes,
154 deserialize_byte_buf,
155 deserialize_option,
156 deserialize_unit,
157 deserialize_seq,
158 deserialize_map,
159 deserialize_identifier,
160 deserialize_ignored_any
161 }
162
163 fn deserialize_unit_struct<V>(
164 self,
165 _name: &'static str,
166 visitor: V,
167 ) -> Result<V::Value, Self::Error>
168 where
169 V: serde::de::Visitor<'de>,
170 {
171 self.deserialize_any(visitor)
172 }
173
174 fn deserialize_newtype_struct<V>(
175 self,
176 _name: &'static str,
177 visitor: V,
178 ) -> Result<V::Value, Self::Error>
179 where
180 V: serde::de::Visitor<'de>,
181 {
182 self.deserialize_any(visitor)
183 }
184
185 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
186 where
187 V: serde::de::Visitor<'de>,
188 {
189 self.deserialize_any(visitor)
190 }
191
192 fn deserialize_tuple_struct<V>(
193 self,
194 _name: &'static str,
195 _len: usize,
196 visitor: V,
197 ) -> Result<V::Value, Self::Error>
198 where
199 V: serde::de::Visitor<'de>,
200 {
201 self.deserialize_any(visitor)
202 }
203
204 fn deserialize_struct<V>(
205 self,
206 _name: &'static str,
207 _fields: &'static [&'static str],
208 visitor: V,
209 ) -> Result<V::Value, Self::Error>
210 where
211 V: serde::de::Visitor<'de>,
212 {
213 self.deserialize_any(visitor)
214 }
215
216 fn deserialize_enum<V>(
217 self,
218 _name: &'static str,
219 _variants: &'static [&'static str],
220 visitor: V,
221 ) -> Result<V::Value, Self::Error>
222 where
223 V: serde::de::Visitor<'de>,
224 {
225 self.deserialize_any(visitor)
226 }
227}
228
229pub fn from_str<'a, T>(s: &'a str) -> Result<T, serde_json::Error>
230where
231 T: serde::Deserialize<'a>,
232{
233 let de = AleoDeserializer::new(s);
234 T::deserialize(de)
235}
236
237#[derive(Debug)]
238pub struct Address {
239 pub address: String,
240}
241
242impl<'de> serde::Deserialize<'de> for Address {
243 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
244 where
245 D: serde::Deserializer<'de>,
246 {
247 let value = String::deserialize(deserializer)?;
248 Ok(Address { address: value })
249 }
250}
251
252#[cfg(test)]
253mod tests {
254 use serde::Deserialize;
255
256 use super::*;
257
258 #[test]
259 fn test_parse_struct() {
260 #[derive(Debug, Deserialize)]
261 #[allow(dead_code)]
262 struct TestStruct {
263 program_id: String,
264 function_name: String,
265 arguments: Vec<Address>,
266 struct2: TestStruct2,
267 vec3: Vec<TestStruct2>,
268 }
269
270 #[derive(Debug, Deserialize)]
271 #[allow(dead_code)]
272 struct TestStruct2 {
273 program_id: String,
274 function_name: String,
275 arguments: (Address, u64),
276 }
277
278 let input = r#"
279 {
280 program_id: puzzle_arcade_ticket_v002.aleo,
281 function_name: mint,
282 arguments: [
283 aleo13dn2lyphtrn8mujxcqt4vm2rc567k0s3gnnks985p0hhyvfc9yqqy6rdsl
284 ],
285 struct2: {
286 program_id: puzzle_arcade_ticket_v002.aleo,
287 function_name: mint,
288 arguments: [
289 aleo13dn2lyphtrn8mujxcqt4vm2rc567k0s3gnnks985p0hhyvfc9yqqy6rdsl,
290 1000u64
291 ]
292 },
293 vec3: [
294 {
295 program_id: puzzle_arcade_ticket_v002.aleo,
296 function_name: mint,
297 arguments: [
298 aleo13dn2lyphtrn8mujxcqt4vm2rc567k0s3gnnks985p0hhyvfc9yqqy6rdsl,
299 1000u64
300 ]
301 }
302 ],
303 extra: extra
304 }
305 "#;
306
307 let result: TestStruct = from_str(input).unwrap();
308 assert_eq!(result.program_id, "puzzle_arcade_ticket_v002.aleo");
309 assert_eq!(result.struct2.arguments.1, 1000);
310
311 let input = r#"
312 [
313 aleo13dn2lyphtrn8mujxcqt4vm2rc567k0s3gnnks985p0hhyvfc9yqqy6rdsl,
314 1000u64
315 ]
316 "#;
317
318 let result: (Address, u64) = from_str(input).unwrap();
319
320 assert_eq!(result.1, 1000);
321
322 let num: u64 = from_str("100u64").unwrap();
323 assert_eq!(num, 100);
324 }
325}