1mod error;
4pub mod help;
5
6use std::str::FromStr;
7
8use serde::{Deserialize, Serialize};
9use serde_json::{json, Value};
10
11use casper_types::{
12 bytesrepr::{ToBytes, OPTION_NONE_TAG, OPTION_SOME_TAG, RESULT_ERR_TAG, RESULT_OK_TAG},
13 AsymmetricType, CLType, CLValue, Key, NamedArg, PublicKey, URef, U128, U256, U512,
14};
15
16use crate::cli::CliError;
17pub use error::{Error, ErrorDetails};
18
19#[derive(Clone, Serialize, Deserialize, Debug)]
21pub struct JsonArg {
22 name: String,
23 #[serde(rename = "type")]
24 cl_type: CLType,
25 value: Value,
26}
27
28impl TryFrom<JsonArg> for NamedArg {
29 type Error = CliError;
30
31 fn try_from(json_arg: JsonArg) -> Result<Self, Self::Error> {
32 let mut bytes = vec![];
33 write_json_to_bytesrepr(&json_arg.cl_type, &json_arg.value, &mut bytes).map_err(
34 |details| {
35 Error::new(
36 json_arg.name.clone(),
37 json_arg.cl_type.clone(),
38 json_arg.value,
39 details,
40 )
41 },
42 )?;
43 Ok(NamedArg::new(
44 json_arg.name,
45 CLValue::from_components(json_arg.cl_type, bytes),
46 ))
47 }
48}
49
50fn write_json_to_bytesrepr(
51 cl_type: &CLType,
52 json_value: &Value,
53 output: &mut Vec<u8>,
54) -> Result<(), ErrorDetails> {
55 match (cl_type, json_value) {
56 (&CLType::Bool, Value::Bool(bool)) => bool.write_bytes(output)?,
57 (&CLType::I32, Value::Number(number)) => {
58 let value = number
59 .as_i64()
60 .and_then(|value| i32::try_from(value).ok())
61 .ok_or(ErrorDetails::CannotParseToI32)?;
62 value.write_bytes(output)?;
63 }
64 (&CLType::I64, Value::Number(number)) => {
65 let value = number.as_i64().ok_or(ErrorDetails::CannotParseToI64)?;
66 value.write_bytes(output)?;
67 }
68 (&CLType::U8, Value::Number(number)) => {
69 let value = number
70 .as_u64()
71 .and_then(|value| u8::try_from(value).ok())
72 .ok_or(ErrorDetails::CannotParseToU8)?;
73 value.write_bytes(output)?;
74 }
75 (&CLType::U32, Value::Number(number)) => {
76 let value = number
77 .as_u64()
78 .and_then(|value| u32::try_from(value).ok())
79 .ok_or(ErrorDetails::CannotParseToU32)?;
80 value.write_bytes(output)?;
81 }
82 (&CLType::U64, Value::Number(number)) => {
83 let value = number.as_u64().ok_or(ErrorDetails::CannotParseToU64)?;
84 value.write_bytes(output)?;
85 }
86 (&CLType::U128, Value::String(string)) => {
87 let value = U128::from_dec_str(string)?;
88 value.write_bytes(output)?;
89 }
90 (&CLType::U128, Value::Number(number)) => {
91 let value = number.as_u64().ok_or(ErrorDetails::CannotParseToU64)?;
92 U128::from(value).write_bytes(output)?;
93 }
94 (&CLType::U256, Value::String(string)) => {
95 let value = U256::from_dec_str(string)?;
96 value.write_bytes(output)?;
97 }
98 (&CLType::U256, Value::Number(number)) => {
99 let value = number.as_u64().ok_or(ErrorDetails::CannotParseToU64)?;
100 U256::from(value).write_bytes(output)?;
101 }
102 (&CLType::U512, Value::String(string)) => {
103 let value = U512::from_dec_str(string)?;
104 value.write_bytes(output)?;
105 }
106 (&CLType::U512, Value::Number(number)) => {
107 let value = number.as_u64().ok_or(ErrorDetails::CannotParseToU64)?;
108 U512::from(value).write_bytes(output)?;
109 }
110 (&CLType::Unit, Value::Null) => (),
111 (&CLType::String, Value::String(string)) => string.write_bytes(output)?,
112 (&CLType::Key, Value::String(string)) => {
113 let value = Key::from_formatted_str(string)?;
114 value.write_bytes(output)?;
115 }
116 (&CLType::Key, Value::Object(map)) => {
117 if map.len() != 1 {
120 return Err(ErrorDetails::KeyObjectHasInvalidNumberOfFields);
121 }
122 let (mapped_variant, mapped_string) = match map.iter().next() {
123 Some((k, Value::String(v))) => (k, v),
124 _ => return Err(ErrorDetails::KeyObjectHasInvalidFieldType),
125 };
126 let value = Key::from_formatted_str(mapped_string)?;
127 match value {
129 Key::Account(_) if mapped_variant == "Account" => {}
130 Key::Hash(_) if mapped_variant == "Hash" => {}
131 Key::URef(_) if mapped_variant == "URef" => {}
132 Key::Transfer(_) if mapped_variant == "Transfer" => {}
133 Key::DeployInfo(_) if mapped_variant == "DeployInfo" => {}
134 Key::EraInfo(_) if mapped_variant == "EraInfo" => {}
135 Key::Balance(_) if mapped_variant == "Balance" => {}
136 Key::Bid(_) if mapped_variant == "Bid" => {}
137 Key::Withdraw(_) if mapped_variant == "Withdraw" => {}
138 Key::Dictionary(_) if mapped_variant == "Dictionary" => {}
139 Key::SystemEntityRegistry if mapped_variant == "SystemEntityRegistry" => {}
140 Key::Unbond(_) if mapped_variant == "Unbond" => {}
141 Key::ChainspecRegistry if mapped_variant == "ChainspecRegistry" => {}
142 _ => return Err(ErrorDetails::KeyObjectHasInvalidVariant),
143 }
144 value.write_bytes(output)?;
145 }
146 (&CLType::URef, Value::String(string)) => {
147 let value = URef::from_formatted_str(string)?;
148 value.write_bytes(output)?;
149 }
150 (&CLType::PublicKey, Value::String(string)) => {
151 let value = PublicKey::from_hex(string)?;
152 value.write_bytes(output)?;
153 }
154 (CLType::Option(ref _inner_cl_type), Value::Null) => {
155 output.push(OPTION_NONE_TAG);
156 }
157 (CLType::Option(ref inner_cl_type), _) => {
158 output.push(OPTION_SOME_TAG);
159 write_json_to_bytesrepr(inner_cl_type, json_value, output)?;
160 }
161 (CLType::List(ref inner_cl_type), Value::Array(vec)) => {
162 (vec.len() as u32).write_bytes(output)?;
163 for item in vec {
164 write_json_to_bytesrepr(inner_cl_type, item, output)?;
165 }
166 }
167 (CLType::List(ref inner_cl_type), Value::String(string)) => {
168 if **inner_cl_type != CLType::U8 {
170 return Err(ErrorDetails::IncompatibleType);
171 }
172 let mut value = base16::decode(string)?;
173 (value.len() as u32).write_bytes(output)?;
174 output.append(&mut value);
175 }
176 (&CLType::ByteArray(expected_length), Value::String(string)) => {
177 let mut value = base16::decode(string)?;
178 let actual_length = value.len() as u32;
179 if actual_length != expected_length {
180 return Err(ErrorDetails::ByteArrayLengthMismatch {
181 expected_length,
182 actual_length,
183 });
184 }
185 output.append(&mut value);
186 }
187 (&CLType::ByteArray(expected_length), Value::Array(array)) => {
188 let actual_length = array.len() as u32;
191 if actual_length != expected_length {
192 return Err(ErrorDetails::ByteArrayLengthMismatch {
193 expected_length,
194 actual_length,
195 });
196 }
197 for value in array {
198 let byte = value
199 .as_u64()
200 .and_then(|value| u8::try_from(value).ok())
201 .ok_or(ErrorDetails::CannotParseToU8)?;
202 output.push(byte);
203 }
204 }
205 (CLType::Result { ref ok, ref err }, Value::Object(map)) => {
206 if map.len() != 1 {
207 return Err(ErrorDetails::ResultObjectHasInvalidNumberOfFields);
208 }
209 match map.iter().next() {
210 Some((key, value)) if key.eq_ignore_ascii_case("ok") => {
211 output.push(RESULT_OK_TAG);
212 write_json_to_bytesrepr(ok, value, output)?;
213 }
214 Some((key, value)) if key.eq_ignore_ascii_case("err") => {
215 output.push(RESULT_ERR_TAG);
216 write_json_to_bytesrepr(err, value, output)?;
217 }
218 _ => return Err(ErrorDetails::ResultObjectHasInvalidVariant),
219 }
220 }
221 (
222 CLType::Map {
223 key: ref key_type,
224 value: ref value_type,
225 },
226 Value::Object(map),
227 ) => {
228 match **key_type {
234 CLType::I32
235 | CLType::I64
236 | CLType::U8
237 | CLType::U32
238 | CLType::U64
239 | CLType::U128
240 | CLType::U256
241 | CLType::U512
242 | CLType::String => (),
243 _ => return Err(ErrorDetails::MapTypeNotValidAsObject(*key_type.clone())),
244 };
245 (map.len() as u32).write_bytes(output)?;
246 for (key_as_str, value) in map {
247 let key = match **key_type {
248 CLType::I32 => json!(i32::from_str(key_as_str)?),
249 CLType::I64 => json!(i64::from_str(key_as_str)?),
250 CLType::U8 => json!(u8::from_str(key_as_str)?),
251 CLType::U32 => json!(u32::from_str(key_as_str)?),
252 CLType::U64 => json!(u64::from_str(key_as_str)?),
253 CLType::U128 => json!(U128::from_dec_str(key_as_str)?),
254 CLType::U256 => json!(U256::from_dec_str(key_as_str)?),
255 CLType::U512 => json!(U512::from_dec_str(key_as_str)?),
256 CLType::String => json!(key_as_str),
257 _ => return Err(ErrorDetails::MapTypeNotValidAsObject(*key_type.clone())),
258 };
259 write_json_to_bytesrepr(key_type, &key, output)?;
260 write_json_to_bytesrepr(value_type, value, output)?;
261 }
262 }
263 (
264 CLType::Map {
265 key: ref key_type,
266 value: ref value_type,
267 },
268 Value::Array(array),
269 ) => {
270 (array.len() as u32).write_bytes(output)?;
271 for item in array {
272 let map = if let Some(map) = item.as_object() {
273 map
274 } else {
275 return Err(ErrorDetails::MapArrayHasInvalidEntryType);
276 };
277 if map.len() != 2 {
278 return Err(ErrorDetails::MapEntryObjectHasInvalidNumberOfFields);
279 }
280 let key = map
281 .get("key")
282 .ok_or(ErrorDetails::MapEntryObjectMissingKeyField)?;
283 write_json_to_bytesrepr(key_type, key, output)?;
284 let value = map
285 .get("value")
286 .ok_or(ErrorDetails::MapEntryObjectMissingValueField)?;
287 write_json_to_bytesrepr(value_type, value, output)?;
288 }
289 }
290 (CLType::Tuple1(ref inner_cl_types), Value::Array(vec)) => {
291 if vec.len() != inner_cl_types.len() {
292 return Err(ErrorDetails::TupleEntryCountMismatch {
293 expected: inner_cl_types.len(),
294 actual: vec.len(),
295 });
296 }
297 write_json_to_bytesrepr(&inner_cl_types[0], &vec[0], output)?;
298 }
299 (CLType::Tuple2(ref inner_cl_types), Value::Array(vec)) => {
300 if vec.len() != inner_cl_types.len() {
301 return Err(ErrorDetails::TupleEntryCountMismatch {
302 expected: inner_cl_types.len(),
303 actual: vec.len(),
304 });
305 }
306 write_json_to_bytesrepr(&inner_cl_types[0], &vec[0], output)?;
307 write_json_to_bytesrepr(&inner_cl_types[1], &vec[1], output)?;
308 }
309 (CLType::Tuple3(ref inner_cl_types), Value::Array(vec)) => {
310 if vec.len() != inner_cl_types.len() {
311 return Err(ErrorDetails::TupleEntryCountMismatch {
312 expected: inner_cl_types.len(),
313 actual: vec.len(),
314 });
315 }
316 write_json_to_bytesrepr(&inner_cl_types[0], &vec[0], output)?;
317 write_json_to_bytesrepr(&inner_cl_types[1], &vec[1], output)?;
318 write_json_to_bytesrepr(&inner_cl_types[2], &vec[2], output)?;
319 }
320 _ => return Err(ErrorDetails::IncompatibleType),
321 };
322 Ok(())
323}
324
325#[cfg(test)]
326mod tests {
327 use std::collections::BTreeMap;
328
329 use casper_types::{account::AccountHash, bytesrepr::Bytes, AccessRights, CLTyped, EraId};
330
331 use super::*;
332
333 const ARRAY: [u8; 32] = [17; 32];
334
335 fn arg_name() -> String {
336 "arg name".to_string()
337 }
338
339 fn create_input(type_str: &str, value_str: &str) -> String {
340 format!(
341 r#"{{"name":"{}","type":{},"value":{}}}"#,
342 arg_name(),
343 type_str,
344 value_str
345 )
346 }
347
348 fn should_parse<T: ToBytes + CLTyped + Serialize>(
349 type_str: &str,
350 value_str: &str,
351 expected: T,
352 ) {
353 let input = create_input(type_str, value_str);
354 let parsed: JsonArg = serde_json::from_str(&input).unwrap();
355 let named_arg = NamedArg::try_from(parsed)
356 .unwrap_or_else(|error| panic!("unexpected error: {}", error));
357 let expected = NamedArg::new(arg_name(), CLValue::from_t(expected).unwrap());
358 assert_eq!(named_arg, expected);
359 }
360
361 fn get_error(type_str: &str, value_str: &str) -> ErrorDetails {
362 let input = create_input(type_str, value_str);
363 let json_arg: JsonArg = serde_json::from_str(&input).unwrap();
364 let mut bytes = vec![];
365 write_json_to_bytesrepr(&json_arg.cl_type, &json_arg.value, &mut bytes).unwrap_err()
366 }
367
368 #[test]
369 fn should_parse_bool() {
370 const TYPE: &str = r#""Bool""#;
371 should_parse(TYPE, "true", true);
372 should_parse(TYPE, "false", false);
373 }
374
375 #[test]
376 fn should_parse_i32() {
377 const TYPE: &str = r#""I32""#;
378 should_parse(TYPE, "-2147483648", i32::MIN);
379 should_parse(TYPE, "-1", -1_i32);
380 should_parse(TYPE, "0", 0_i32);
381 should_parse(TYPE, "1", 1_i32);
382 should_parse(TYPE, "2147483647", i32::MAX);
383 }
384
385 #[test]
386 fn should_parse_i64() {
387 const TYPE: &str = r#""I64""#;
388 should_parse(TYPE, "-9223372036854775808", i64::MIN);
389 should_parse(TYPE, "-1", -1_i64);
390 should_parse(TYPE, "0", 0_i64);
391 should_parse(TYPE, "1", 1_i64);
392 should_parse(TYPE, "9223372036854775807", i64::MAX);
393 }
394
395 #[test]
396 fn should_parse_u8() {
397 const TYPE: &str = r#""U8""#;
398 should_parse(TYPE, "0", 0_u8);
399 should_parse(TYPE, "255", u8::MAX);
400 }
401
402 #[test]
403 fn should_parse_u32() {
404 const TYPE: &str = r#""U32""#;
405 should_parse(TYPE, "0", 0_u32);
406 should_parse(TYPE, "4294967295", u32::MAX);
407 }
408
409 #[test]
410 fn should_parse_u64() {
411 const TYPE: &str = r#""U64""#;
412 should_parse(TYPE, "0", 0_u64);
413 should_parse(TYPE, "18446744073709551615", u64::MAX);
414 }
415
416 #[test]
417 fn should_parse_u128() {
418 const TYPE: &str = r#""U128""#;
419 should_parse(TYPE, r#""0""#, U128::zero());
421 should_parse(
422 TYPE,
423 r#""340282366920938463463374607431768211455""#,
424 U128::MAX,
425 );
426
427 should_parse(TYPE, "0", U128::zero());
429 should_parse(TYPE, "18446744073709551615", U128::from(u64::MAX));
430 }
431
432 #[test]
433 fn should_parse_u256() {
434 const TYPE: &str = r#""U256""#;
435 should_parse(TYPE, r#""0""#, U256::zero());
437 should_parse(
438 TYPE,
439 r#""115792089237316195423570985008687907853269984665640564039457584007913129639935""#,
440 U256::MAX,
441 );
442
443 should_parse(TYPE, "0", U256::zero());
445 should_parse(TYPE, "18446744073709551615", U256::from(u64::MAX));
446 }
447
448 #[test]
449 fn should_parse_u512() {
450 const TYPE: &str = r#""U512""#;
451 should_parse(TYPE, r#""0""#, U512::zero());
453 should_parse(
454 TYPE,
455 r#""13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095""#,
456 U512::MAX,
457 );
458
459 should_parse(TYPE, "0", U512::zero());
461 should_parse(TYPE, "18446744073709551615", U512::from(u64::MAX));
462 }
463
464 #[test]
465 fn should_parse_unit() {
466 const TYPE: &str = r#""Unit""#;
467 should_parse(TYPE, "null", ());
468 }
469
470 #[test]
471 fn should_parse_string() {
472 const TYPE: &str = r#""String""#;
473 should_parse(TYPE, r#""""#, String::new());
474 should_parse(TYPE, r#""some text""#, "some text".to_string());
475 }
476
477 #[test]
478 fn should_parse_key() {
479 const TYPE: &str = r#""Key""#;
480 const UREF: URef = URef::new(ARRAY, AccessRights::NONE);
481
482 should_parse(
484 TYPE,
485 r#""account-hash-1111111111111111111111111111111111111111111111111111111111111111""#,
486 Key::Account(AccountHash::new(ARRAY)),
487 );
488 should_parse(
490 TYPE,
491 r#"{"Account":"account-hash-1111111111111111111111111111111111111111111111111111111111111111"}"#,
492 Key::Account(AccountHash::new(ARRAY)),
493 );
494
495 should_parse(
497 TYPE,
498 r#""hash-1111111111111111111111111111111111111111111111111111111111111111""#,
499 Key::Hash(ARRAY),
500 );
501 should_parse(
503 TYPE,
504 r#"{"Hash":"hash-1111111111111111111111111111111111111111111111111111111111111111"}"#,
505 Key::Hash(ARRAY),
506 );
507
508 should_parse(
510 TYPE,
511 r#""uref-1111111111111111111111111111111111111111111111111111111111111111-000""#,
512 Key::URef(UREF),
513 );
514 should_parse(
516 TYPE,
517 r#"{"URef":"uref-1111111111111111111111111111111111111111111111111111111111111111-000"}"#,
518 Key::URef(UREF),
519 );
520
521 should_parse(TYPE, r#""era-1""#, Key::EraInfo(EraId::new(1)));
523 should_parse(TYPE, r#"{"EraInfo":"era-1"}"#, Key::EraInfo(EraId::new(1)));
525 }
526
527 #[test]
528 fn should_parse_uref() {
529 const TYPE: &str = r#""URef""#;
530 should_parse(
531 TYPE,
532 r#""uref-1111111111111111111111111111111111111111111111111111111111111111-007""#,
533 URef::new(ARRAY, AccessRights::all()),
534 );
535 }
536
537 #[test]
538 fn should_parse_public_key() {
539 const TYPE: &str = r#""PublicKey""#;
540 should_parse(
541 TYPE,
542 r#""011111111111111111111111111111111111111111111111111111111111111111""#,
543 PublicKey::ed25519_from_bytes(ARRAY).unwrap(),
544 );
545 }
546
547 #[test]
548 fn should_parse_option() {
549 const SIMPLE_TYPE: &str = r#"{"Option":"U64"}"#;
550 should_parse(SIMPLE_TYPE, "999", Some(999_u64));
551 should_parse::<Option<u64>>(SIMPLE_TYPE, "null", None);
552
553 const COMPLEX_TYPE: &str = r#"{"Option":{"Tuple2":["Bool","U8"]}}"#;
554 should_parse(COMPLEX_TYPE, "[true,1]", Some((true, 1_u8)));
555 should_parse::<Option<(bool, u8)>>(COMPLEX_TYPE, "null", None);
556 }
557
558 #[test]
559 fn should_parse_list() {
560 const SIMPLE_TYPE: &str = r#"{"List":"U64"}"#;
561 should_parse(SIMPLE_TYPE, "[1,2,3]", vec![1_u64, 2, 3]);
562 should_parse(SIMPLE_TYPE, "[]", Vec::<u64>::new());
563
564 const COMPLEX_TYPE: &str = r#"{"List":{"Option":{"Tuple2":["Bool","U8"]}}}"#;
565 should_parse(
566 COMPLEX_TYPE,
567 "[[true,1],null,[false,2]]",
568 vec![Some((true, 1_u8)), None, Some((false, 2))],
569 );
570 should_parse(COMPLEX_TYPE, "[]", Vec::<Option<(bool, u8)>>::new());
571
572 const BYTE_LIST_TYPE: &str = r#"{"List":"U8"}"#;
574 should_parse(
575 BYTE_LIST_TYPE,
576 r#""0102ff""#,
577 Bytes::from(vec![1_u8, 2, 255]),
578 );
579 should_parse(BYTE_LIST_TYPE, r#""""#, Bytes::from(vec![]));
580 }
581
582 #[test]
583 fn should_parse_byte_array() {
584 const BYTE_ARRAY_3_TYPE: &str = r#"{"ByteArray":3}"#;
585 const BYTE_ARRAY_3: [u8; 3] = [1, 20, 255];
586 should_parse(BYTE_ARRAY_3_TYPE, r#""0114ff""#, BYTE_ARRAY_3);
588 should_parse(BYTE_ARRAY_3_TYPE, "[1,20,255]", BYTE_ARRAY_3);
590
591 const BYTE_ARRAY_EMPTY_TYPE: &str = r#"{"ByteArray":0}"#;
592 should_parse(BYTE_ARRAY_EMPTY_TYPE, r#""""#, []);
594 should_parse(BYTE_ARRAY_EMPTY_TYPE, "[]", []);
596 }
597
598 #[test]
599 fn should_parse_result() {
600 const SIMPLE_TYPE: &str = r#"{"Result":{"ok":"Bool","err":"U8"}}"#;
601
602 should_parse::<Result<bool, u8>>(SIMPLE_TYPE, r#"{"Ok":true}"#, Ok(true));
603 should_parse::<Result<bool, u8>>(SIMPLE_TYPE, r#"{"ok":true}"#, Ok(true));
604 should_parse::<Result<bool, u8>>(SIMPLE_TYPE, r#"{"Err":1}"#, Err(1));
605 should_parse::<Result<bool, u8>>(SIMPLE_TYPE, r#"{"err":1}"#, Err(1));
606
607 const COMPLEX_TYPE: &str =
608 r#"{"Result":{"ok":{"Option":{"Tuple2":["Bool","U8"]}},"err":{"Option":"String"}}}"#;
609 should_parse::<Result<Option<(bool, u8)>, Option<String>>>(
610 COMPLEX_TYPE,
611 r#"{"Ok":[true,255]}"#,
612 Ok(Some((true, 255))),
613 );
614 should_parse::<Result<Option<(bool, u8)>, Option<String>>>(
615 COMPLEX_TYPE,
616 r#"{"Err":"failed"}"#,
617 Err(Some("failed".to_string())),
618 );
619 }
620
621 #[test]
622 fn should_parse_map() {
623 const SIMPLE_TYPE: &str = r#"{"Map":{"key":"U8","value":"Bool"}}"#;
624 let mut simple_map = BTreeMap::new();
625 simple_map.insert(1_u8, true);
626 simple_map.insert(2, false);
627
628 let value_str = r#"{"1":true,"2":false}"#;
630 assert_eq!(value_str, serde_json::to_string(&simple_map).unwrap());
631 should_parse(SIMPLE_TYPE, value_str, simple_map.clone());
632 should_parse(
634 SIMPLE_TYPE,
635 r#"[{"key":1,"value":true},{"key":2,"value":false}]"#,
636 simple_map,
637 );
638
639 should_parse(SIMPLE_TYPE, "{}", BTreeMap::<u8, bool>::new());
641 should_parse(SIMPLE_TYPE, "[]", BTreeMap::<u8, bool>::new());
643
644 const COMPLEX_TYPE: &str =
645 r#"{"Map":{"key":{"List":"U64"},"value":{"Map":{"key":"U8","value":"Bool"}}}}"#;
646 let list1 = vec![1_u64, 2, 3];
647 let mut simple_map1 = BTreeMap::new();
648 simple_map1.insert(10_u8, true);
649 simple_map1.insert(20, false);
650 let list2 = vec![4_u64, 5, 6];
651 let mut simple_map2 = BTreeMap::new();
652 simple_map2.insert(30_u8, true);
653 simple_map2.insert(40, false);
654 let mut complex_map = BTreeMap::new();
655 complex_map.insert(list1, simple_map1);
656 complex_map.insert(list2, simple_map2);
657 assert!(serde_json::to_string(&complex_map).is_err());
658
659 let input = create_input(COMPLEX_TYPE, value_str);
661 let parsed: JsonArg = serde_json::from_str(&input).unwrap();
662 assert!(NamedArg::try_from(parsed).is_err());
663
664 should_parse(
666 COMPLEX_TYPE,
667 r#"[{"key":[1,2,3],"value":{"10":true,"20":false}},{"key":[4,5,6],"value":{"30":true,"40":false}}]"#,
668 complex_map,
669 );
670 }
671
672 #[test]
673 fn should_parse_tuple1() {
674 const SIMPLE_TYPE: &str = r#"{"Tuple1":["Bool"]}"#;
675 should_parse(SIMPLE_TYPE, "[true]", (true,));
676
677 const COMPLEX_TYPE: &str =
678 r#"{"Tuple1":[{"Result":{"ok":{"Option":"String"},"err":"I32"}}]}"#;
679 should_parse::<(Result<Option<String>, i32>,)>(
680 COMPLEX_TYPE,
681 r#"[{"Ok":null}]"#,
682 (Ok(None),),
683 );
684 }
685
686 #[test]
687 fn should_parse_tuple2() {
688 const SIMPLE_TYPE: &str = r#"{"Tuple2":["Bool","U8"]}"#;
689 should_parse(SIMPLE_TYPE, "[true,128]", (true, 128_u8));
690
691 const COMPLEX_TYPE1: &str =
692 r#"{"Tuple2":[{"Result":{"ok":{"Option":"String"},"err":"I32"}},"Bool"]}"#;
693 should_parse::<(Result<Option<String>, i32>, bool)>(
694 COMPLEX_TYPE1,
695 r#"[{"Ok":null},true]"#,
696 (Ok(None), true),
697 );
698
699 const COMPLEX_TYPE2: &str =
700 r#"{"Tuple2":["Bool",{"Result":{"ok":{"Option":"String"},"err":"I32"}}]}"#;
701 should_parse::<(bool, Result<Option<String>, i32>)>(
702 COMPLEX_TYPE2,
703 r#"[true,{"Ok":null}]"#,
704 (true, Ok(None)),
705 );
706 }
707
708 #[test]
709 fn should_parse_tuple3() {
710 const SIMPLE_TYPE: &str = r#"{"Tuple3":["Bool","U8","String"]}"#;
711 should_parse(
712 SIMPLE_TYPE,
713 r#"[true,128,"a"]"#,
714 (true, 128_u8, "a".to_string()),
715 );
716
717 const COMPLEX_TYPE1: &str =
718 r#"{"Tuple3":[{"Result":{"ok":{"Option":"String"},"err":"I32"}},"Bool","Unit"]}"#;
719 should_parse::<(Result<Option<String>, i32>, bool, ())>(
720 COMPLEX_TYPE1,
721 r#"[{"Ok":null},true,null]"#,
722 (Ok(None), true, ()),
723 );
724
725 const COMPLEX_TYPE2: &str =
726 r#"{"Tuple3":["Bool",{"Result":{"ok":{"Option":"String"},"err":"I32"}},"Unit"]}"#;
727 should_parse::<(bool, Result<Option<String>, i32>, ())>(
728 COMPLEX_TYPE2,
729 r#"[true,{"Ok":null},null]"#,
730 (true, Ok(None), ()),
731 );
732
733 const COMPLEX_TYPE3: &str =
734 r#"{"Tuple3":["Bool","Unit",{"Result":{"ok":{"Option":"String"},"err":"I32"}}]}"#;
735 should_parse::<(bool, (), Result<Option<String>, i32>)>(
736 COMPLEX_TYPE3,
737 r#"[true,null,{"Ok":null}]"#,
738 (true, (), Ok(None)),
739 );
740 }
741
742 #[test]
743 fn should_fail_to_parse_key_from_object() {
744 const TYPE: &str = r#""Key""#;
745
746 let error = get_error(TYPE, r#"{"EraInfo":"era-1","extra field":null}"#);
748 assert!(
749 matches!(error, ErrorDetails::KeyObjectHasInvalidNumberOfFields),
750 "{}",
751 error
752 );
753
754 let error = get_error(TYPE, "{}");
756 assert!(
757 matches!(error, ErrorDetails::KeyObjectHasInvalidNumberOfFields),
758 "{}",
759 error
760 );
761
762 let error = get_error(TYPE, r#"{"not a key variant":"era-1"}"#);
764 assert!(
765 matches!(error, ErrorDetails::KeyObjectHasInvalidVariant),
766 "{}",
767 error
768 );
769
770 let error = get_error(TYPE, r#"{"EraInfo":["era-1"]}"#);
772 assert!(
773 matches!(error, ErrorDetails::KeyObjectHasInvalidFieldType),
774 "{}",
775 error
776 );
777
778 let error = get_error(TYPE, r#"{"EraInfo":"er-1"}"#);
780 assert!(
781 matches!(error, ErrorDetails::ParseKeyFromString(_)),
782 "{}",
783 error
784 );
785 }
786
787 #[test]
788 fn should_fail_to_parse_byte_array() {
789 const TYPE: &str = r#"{"ByteArray":3}"#;
790
791 let error = get_error(TYPE, r#""01020304""#);
793 assert!(
794 matches!(
795 error,
796 ErrorDetails::ByteArrayLengthMismatch {
797 expected_length: 3,
798 actual_length: 4
799 }
800 ),
801 "{}",
802 error
803 );
804
805 let error = get_error(TYPE, r#""01020g""#);
807 assert!(matches!(error, ErrorDetails::HexDecode(_)), "{}", error);
808
809 let error = get_error(TYPE, "[1,2,3,4]");
811 assert!(
812 matches!(
813 error,
814 ErrorDetails::ByteArrayLengthMismatch {
815 expected_length: 3,
816 actual_length: 4
817 }
818 ),
819 "{}",
820 error
821 );
822
823 let error = get_error(TYPE, "[1,2,256]");
825 assert!(matches!(error, ErrorDetails::CannotParseToU8), "{}", error);
826 }
827
828 #[test]
829 fn should_fail_to_parse_result() {
830 const TYPE: &str = r#"{"Result":{"ok":"Bool","err":"U8"}}"#;
831
832 let error = get_error(TYPE, r#"{"Ok":true,"extra field":null}"#);
834 assert!(
835 matches!(error, ErrorDetails::ResultObjectHasInvalidNumberOfFields),
836 "{}",
837 error
838 );
839
840 let error = get_error(TYPE, "{}");
842 assert!(
843 matches!(error, ErrorDetails::ResultObjectHasInvalidNumberOfFields),
844 "{}",
845 error
846 );
847
848 let error = get_error(TYPE, r#"{"A-ok":true}"#);
850 assert!(
851 matches!(error, ErrorDetails::ResultObjectHasInvalidVariant),
852 "{}",
853 error
854 );
855 }
856
857 #[test]
858 fn should_fail_to_parse_map_from_object() {
859 const INVALID_KEY_TYPE_FOR_OBJECT: &str = r#"{"Map":{"key":"Bool","value":"U8"}}"#;
860
861 let error = get_error(INVALID_KEY_TYPE_FOR_OBJECT, r#"{"true":1}"#);
863 assert!(
864 matches!(error, ErrorDetails::MapTypeNotValidAsObject(CLType::Bool)),
865 "{}",
866 error
867 );
868
869 let error = get_error(INVALID_KEY_TYPE_FOR_OBJECT, "{}");
871 assert!(
872 matches!(error, ErrorDetails::MapTypeNotValidAsObject(CLType::Bool)),
873 "{}",
874 error
875 );
876 }
877
878 #[test]
879 fn should_fail_to_parse_map_from_array() {
880 const TYPE: &str = r#"{"Map":{"key":"U8","value":"Bool"}}"#;
881
882 let error = get_error(TYPE, r#"[{"key":1,"value":true},"non-object entry"]"#);
884 assert!(
885 matches!(error, ErrorDetails::MapArrayHasInvalidEntryType),
886 "{}",
887 error
888 );
889
890 let error = get_error(
892 TYPE,
893 r#"[{"key":1,"value":true},{"key":2,"value":false,"extra field":null}]"#,
894 );
895 assert!(
896 matches!(error, ErrorDetails::MapEntryObjectHasInvalidNumberOfFields),
897 "{}",
898 error
899 );
900
901 let error = get_error(
903 TYPE,
904 r#"[{"key":1,"value":true},{"not key":2,"value":false}]"#,
905 );
906 assert!(
907 matches!(error, ErrorDetails::MapEntryObjectMissingKeyField),
908 "{}",
909 error
910 );
911
912 let error = get_error(
914 TYPE,
915 r#"[{"key":1,"value":true},{"key":2,"not value":false}]"#,
916 );
917 assert!(
918 matches!(error, ErrorDetails::MapEntryObjectMissingValueField),
919 "{}",
920 error
921 );
922 }
923
924 #[test]
925 fn should_fail_to_parse_tuple1() {
926 const TYPE: &str = r#"{"Tuple1":["Bool"]}"#;
927
928 let error = get_error(TYPE, "[]");
930 assert!(
931 matches!(
932 error,
933 ErrorDetails::TupleEntryCountMismatch {
934 expected: 1,
935 actual: 0
936 }
937 ),
938 "{}",
939 error
940 );
941
942 let error = get_error(TYPE, "[true,1]");
944 assert!(
945 matches!(
946 error,
947 ErrorDetails::TupleEntryCountMismatch {
948 expected: 1,
949 actual: 2
950 }
951 ),
952 "{}",
953 error
954 );
955 }
956
957 #[test]
958 fn should_fail_to_parse_tuple2() {
959 const TYPE: &str = r#"{"Tuple2":["Bool","U8"]}"#;
960
961 let error = get_error(TYPE, "[true]");
963 assert!(
964 matches!(
965 error,
966 ErrorDetails::TupleEntryCountMismatch {
967 expected: 2,
968 actual: 1
969 }
970 ),
971 "{}",
972 error
973 );
974
975 let error = get_error(TYPE, "[true,1,null]");
977 assert!(
978 matches!(
979 error,
980 ErrorDetails::TupleEntryCountMismatch {
981 expected: 2,
982 actual: 3
983 }
984 ),
985 "{}",
986 error
987 );
988 }
989
990 #[test]
991 fn should_fail_to_parse_tuple3() {
992 const TYPE: &str = r#"{"Tuple3":["Bool","U8","String"]}"#;
993
994 let error = get_error(TYPE, "[true,1]");
996 assert!(
997 matches!(
998 error,
999 ErrorDetails::TupleEntryCountMismatch {
1000 expected: 3,
1001 actual: 2
1002 }
1003 ),
1004 "{}",
1005 error
1006 );
1007
1008 let error = get_error(TYPE, r#"[true,1,"a",null]"#);
1010 assert!(
1011 matches!(
1012 error,
1013 ErrorDetails::TupleEntryCountMismatch {
1014 expected: 3,
1015 actual: 4
1016 }
1017 ),
1018 "{}",
1019 error
1020 );
1021 }
1022}