casper_types/
cl_value.rs

1// TODO - remove once schemars stops causing warning.
2#![allow(clippy::field_reassign_with_default)]
3
4use alloc::{string::String, vec::Vec};
5use core::fmt::{self, Display, Formatter};
6
7#[cfg(feature = "datasize")]
8use datasize::DataSize;
9#[cfg(feature = "json-schema")]
10use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
11use serde::{de::Error as SerdeError, Deserialize, Deserializer, Serialize, Serializer};
12use serde_json::Value;
13
14use crate::{
15    bytesrepr::{self, Bytes, FromBytes, ToBytes, U32_SERIALIZED_LENGTH},
16    checksummed_hex, CLType, CLTyped,
17};
18
19mod jsonrepr;
20
21/// Error while converting a [`CLValue`] into a given type.
22#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
23#[cfg_attr(feature = "datasize", derive(DataSize))]
24pub struct CLTypeMismatch {
25    /// The [`CLType`] into which the `CLValue` was being converted.
26    pub expected: CLType,
27    /// The actual underlying [`CLType`] of this `CLValue`, i.e. the type from which it was
28    /// constructed.
29    pub found: CLType,
30}
31
32impl Display for CLTypeMismatch {
33    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
34        write!(
35            f,
36            "Expected {:?} but found {:?}.",
37            self.expected, self.found
38        )
39    }
40}
41
42/// Error relating to [`CLValue`] operations.
43#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
44#[cfg_attr(feature = "datasize", derive(DataSize))]
45pub enum CLValueError {
46    /// An error while serializing or deserializing the underlying data.
47    Serialization(bytesrepr::Error),
48    /// A type mismatch while trying to convert a [`CLValue`] into a given type.
49    Type(CLTypeMismatch),
50}
51
52impl From<bytesrepr::Error> for CLValueError {
53    fn from(error: bytesrepr::Error) -> Self {
54        CLValueError::Serialization(error)
55    }
56}
57
58impl Display for CLValueError {
59    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
60        match self {
61            CLValueError::Serialization(error) => write!(formatter, "CLValue error: {}", error),
62            CLValueError::Type(error) => write!(formatter, "Type mismatch: {}", error),
63        }
64    }
65}
66
67/// A Casper value, i.e. a value which can be stored and manipulated by smart contracts.
68///
69/// It holds the underlying data as a type-erased, serialized `Vec<u8>` and also holds the
70/// [`CLType`] of the underlying data as a separate member.
71#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Debug)]
72#[cfg_attr(feature = "datasize", derive(DataSize))]
73pub struct CLValue {
74    cl_type: CLType,
75    bytes: Bytes,
76}
77
78impl CLValue {
79    /// Constructs a `CLValue` from `t`.
80    pub fn from_t<T: CLTyped + ToBytes>(t: T) -> Result<CLValue, CLValueError> {
81        let bytes = t.into_bytes()?;
82
83        Ok(CLValue {
84            cl_type: T::cl_type(),
85            bytes: bytes.into(),
86        })
87    }
88
89    /// Consumes and converts `self` back into its underlying type.
90    pub fn into_t<T: CLTyped + FromBytes>(self) -> Result<T, CLValueError> {
91        let expected = T::cl_type();
92
93        if self.cl_type == expected {
94            Ok(bytesrepr::deserialize_from_slice(&self.bytes)?)
95        } else {
96            Err(CLValueError::Type(CLTypeMismatch {
97                expected,
98                found: self.cl_type,
99            }))
100        }
101    }
102
103    /// A convenience method to create CLValue for a unit.
104    pub fn unit() -> Self {
105        CLValue::from_components(CLType::Unit, Vec::new())
106    }
107
108    /// Is the CLValue a unit value.
109    pub fn is_unit(&self) -> bool {
110        self.cl_type == CLType::Unit
111    }
112
113    // This is only required in order to implement `TryFrom<state::CLValue> for CLValue` (i.e. the
114    // conversion from the Protobuf `CLValue`) in a separate module to this one.
115    #[doc(hidden)]
116    pub fn from_components(cl_type: CLType, bytes: Vec<u8>) -> Self {
117        Self {
118            cl_type,
119            bytes: bytes.into(),
120        }
121    }
122
123    // This is only required in order to implement `From<CLValue> for state::CLValue` (i.e. the
124    // conversion to the Protobuf `CLValue`) in a separate module to this one.
125    #[doc(hidden)]
126    pub fn destructure(self) -> (CLType, Bytes) {
127        (self.cl_type, self.bytes)
128    }
129
130    /// The [`CLType`] of the underlying data.
131    pub fn cl_type(&self) -> &CLType {
132        &self.cl_type
133    }
134
135    /// Returns a reference to the serialized form of the underlying value held in this `CLValue`.
136    pub fn inner_bytes(&self) -> &Vec<u8> {
137        self.bytes.inner_bytes()
138    }
139
140    /// Returns the length of the `Vec<u8>` yielded after calling `self.to_bytes()`.
141    ///
142    /// Note, this method doesn't actually serialize `self`, and hence is relatively cheap.
143    pub fn serialized_length(&self) -> usize {
144        self.cl_type.serialized_length() + U32_SERIALIZED_LENGTH + self.bytes.len()
145    }
146}
147
148impl ToBytes for CLValue {
149    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
150        self.clone().into_bytes()
151    }
152
153    fn into_bytes(self) -> Result<Vec<u8>, bytesrepr::Error> {
154        let mut result = self.bytes.into_bytes()?;
155        self.cl_type.append_bytes(&mut result)?;
156        Ok(result)
157    }
158
159    fn serialized_length(&self) -> usize {
160        self.bytes.serialized_length() + self.cl_type.serialized_length()
161    }
162
163    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
164        self.bytes.write_bytes(writer)?;
165        self.cl_type.append_bytes(writer)?;
166        Ok(())
167    }
168}
169
170impl FromBytes for CLValue {
171    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
172        let (bytes, remainder) = FromBytes::from_bytes(bytes)?;
173        let (cl_type, remainder) = FromBytes::from_bytes(remainder)?;
174        let cl_value = CLValue { cl_type, bytes };
175        Ok((cl_value, remainder))
176    }
177}
178
179/// We need to implement `JsonSchema` for `CLValue` as though it is a `CLValueJson`.
180#[cfg(feature = "json-schema")]
181impl JsonSchema for CLValue {
182    fn schema_name() -> String {
183        "CLValue".to_string()
184    }
185
186    fn json_schema(gen: &mut SchemaGenerator) -> Schema {
187        <CLValueJson>::json_schema(gen)
188    }
189}
190
191/// A Casper value, i.e. a value which can be stored and manipulated by smart contracts.
192///
193/// It holds the underlying data as a type-erased, serialized `Vec<u8>` and also holds the CLType of
194/// the underlying data as a separate member.
195///
196/// The `parsed` field, representing the original value, is a convenience only available when a
197/// CLValue is encoded to JSON, and can always be set to null if preferred.
198#[derive(Serialize, Deserialize)]
199#[serde(deny_unknown_fields)]
200#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
201#[cfg_attr(feature = "json-schema", schemars(rename = "CLValue"))]
202struct CLValueJson {
203    cl_type: CLType,
204    bytes: String,
205    parsed: Option<Value>,
206}
207
208impl Serialize for CLValue {
209    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
210        if serializer.is_human_readable() {
211            CLValueJson {
212                cl_type: self.cl_type.clone(),
213                bytes: base16::encode_lower(&self.bytes),
214                parsed: jsonrepr::cl_value_to_json(self),
215            }
216            .serialize(serializer)
217        } else {
218            (&self.cl_type, &self.bytes).serialize(serializer)
219        }
220    }
221}
222
223impl<'de> Deserialize<'de> for CLValue {
224    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
225        let (cl_type, bytes) = if deserializer.is_human_readable() {
226            let json = CLValueJson::deserialize(deserializer)?;
227            (
228                json.cl_type.clone(),
229                checksummed_hex::decode(&json.bytes).map_err(D::Error::custom)?,
230            )
231        } else {
232            <(CLType, Vec<u8>)>::deserialize(deserializer)?
233        };
234        Ok(CLValue {
235            cl_type,
236            bytes: bytes.into(),
237        })
238    }
239}
240
241#[cfg(test)]
242mod tests {
243    use alloc::string::ToString;
244
245    #[cfg(feature = "json-schema")]
246    use schemars::schema_for;
247
248    use super::*;
249    use crate::{
250        account::{AccountHash, ACCOUNT_HASH_LENGTH},
251        key::KEY_HASH_LENGTH,
252        AccessRights, DeployHash, Key, PublicKey, TransferAddr, URef, DEPLOY_HASH_LENGTH,
253        TRANSFER_ADDR_LENGTH, U128, U256, U512, UREF_ADDR_LENGTH,
254    };
255
256    #[cfg(feature = "json-schema")]
257    #[test]
258    fn json_schema() {
259        let json_clvalue_schema = schema_for!(CLValueJson);
260        let clvalue_schema = schema_for!(CLValue);
261        assert_eq!(json_clvalue_schema, clvalue_schema);
262    }
263
264    #[test]
265    fn serde_roundtrip() {
266        let cl_value = CLValue::from_t(true).unwrap();
267        let serialized = bincode::serialize(&cl_value).unwrap();
268        let decoded = bincode::deserialize(&serialized).unwrap();
269        assert_eq!(cl_value, decoded);
270    }
271
272    #[test]
273    fn json_roundtrip() {
274        let cl_value = CLValue::from_t(true).unwrap();
275        let json_string = serde_json::to_string_pretty(&cl_value).unwrap();
276        let decoded = serde_json::from_str(&json_string).unwrap();
277        assert_eq!(cl_value, decoded);
278    }
279
280    fn check_to_json<T: CLTyped + ToBytes + FromBytes>(value: T, expected: &str) {
281        let cl_value = CLValue::from_t(value).unwrap();
282        let cl_value_as_json = serde_json::to_string(&cl_value).unwrap();
283        // Remove the `serialized_bytes` field:
284        // Split the string at `,"serialized_bytes":`.
285        let pattern = r#","bytes":""#;
286        let start_index = cl_value_as_json.find(pattern).unwrap();
287        let (start, end) = cl_value_as_json.split_at(start_index);
288        // Find the end of the value of the `bytes` field, and split there.
289        let mut json_without_serialize_bytes = start.to_string();
290        for (index, char) in end.char_indices().skip(pattern.len()) {
291            if char == '"' {
292                let (_to_remove, to_keep) = end.split_at(index + 1);
293                json_without_serialize_bytes.push_str(to_keep);
294                break;
295            }
296        }
297        assert_eq!(json_without_serialize_bytes, expected);
298    }
299
300    mod simple_types {
301        use super::*;
302        use crate::crypto::SecretKey;
303
304        #[test]
305        fn bool_cl_value_should_encode_to_json() {
306            check_to_json(true, r#"{"cl_type":"Bool","parsed":true}"#);
307            check_to_json(false, r#"{"cl_type":"Bool","parsed":false}"#);
308        }
309
310        #[test]
311        fn i32_cl_value_should_encode_to_json() {
312            check_to_json(
313                i32::min_value(),
314                r#"{"cl_type":"I32","parsed":-2147483648}"#,
315            );
316            check_to_json(0_i32, r#"{"cl_type":"I32","parsed":0}"#);
317            check_to_json(i32::max_value(), r#"{"cl_type":"I32","parsed":2147483647}"#);
318        }
319
320        #[test]
321        fn i64_cl_value_should_encode_to_json() {
322            check_to_json(
323                i64::min_value(),
324                r#"{"cl_type":"I64","parsed":-9223372036854775808}"#,
325            );
326            check_to_json(0_i64, r#"{"cl_type":"I64","parsed":0}"#);
327            check_to_json(
328                i64::max_value(),
329                r#"{"cl_type":"I64","parsed":9223372036854775807}"#,
330            );
331        }
332
333        #[test]
334        fn u8_cl_value_should_encode_to_json() {
335            check_to_json(0_u8, r#"{"cl_type":"U8","parsed":0}"#);
336            check_to_json(u8::max_value(), r#"{"cl_type":"U8","parsed":255}"#);
337        }
338
339        #[test]
340        fn u32_cl_value_should_encode_to_json() {
341            check_to_json(0_u32, r#"{"cl_type":"U32","parsed":0}"#);
342            check_to_json(u32::max_value(), r#"{"cl_type":"U32","parsed":4294967295}"#);
343        }
344
345        #[test]
346        fn u64_cl_value_should_encode_to_json() {
347            check_to_json(0_u64, r#"{"cl_type":"U64","parsed":0}"#);
348            check_to_json(
349                u64::max_value(),
350                r#"{"cl_type":"U64","parsed":18446744073709551615}"#,
351            );
352        }
353
354        #[test]
355        fn u128_cl_value_should_encode_to_json() {
356            check_to_json(U128::zero(), r#"{"cl_type":"U128","parsed":"0"}"#);
357            check_to_json(
358                U128::max_value(),
359                r#"{"cl_type":"U128","parsed":"340282366920938463463374607431768211455"}"#,
360            );
361        }
362
363        #[test]
364        fn u256_cl_value_should_encode_to_json() {
365            check_to_json(U256::zero(), r#"{"cl_type":"U256","parsed":"0"}"#);
366            check_to_json(
367                U256::max_value(),
368                r#"{"cl_type":"U256","parsed":"115792089237316195423570985008687907853269984665640564039457584007913129639935"}"#,
369            );
370        }
371
372        #[test]
373        fn u512_cl_value_should_encode_to_json() {
374            check_to_json(U512::zero(), r#"{"cl_type":"U512","parsed":"0"}"#);
375            check_to_json(
376                U512::max_value(),
377                r#"{"cl_type":"U512","parsed":"13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095"}"#,
378            );
379        }
380
381        #[test]
382        fn unit_cl_value_should_encode_to_json() {
383            check_to_json((), r#"{"cl_type":"Unit","parsed":null}"#);
384        }
385
386        #[test]
387        fn string_cl_value_should_encode_to_json() {
388            check_to_json(String::new(), r#"{"cl_type":"String","parsed":""}"#);
389            check_to_json(
390                "test string".to_string(),
391                r#"{"cl_type":"String","parsed":"test string"}"#,
392            );
393        }
394
395        #[test]
396        fn key_cl_value_should_encode_to_json() {
397            let key_account = Key::Account(AccountHash::new([1; ACCOUNT_HASH_LENGTH]));
398            check_to_json(
399                key_account,
400                r#"{"cl_type":"Key","parsed":{"Account":"account-hash-0101010101010101010101010101010101010101010101010101010101010101"}}"#,
401            );
402
403            let key_hash = Key::Hash([2; KEY_HASH_LENGTH]);
404            check_to_json(
405                key_hash,
406                r#"{"cl_type":"Key","parsed":{"Hash":"hash-0202020202020202020202020202020202020202020202020202020202020202"}}"#,
407            );
408
409            let key_uref = Key::URef(URef::new([3; UREF_ADDR_LENGTH], AccessRights::READ));
410            check_to_json(
411                key_uref,
412                r#"{"cl_type":"Key","parsed":{"URef":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}}"#,
413            );
414
415            let key_transfer = Key::Transfer(TransferAddr::new([4; TRANSFER_ADDR_LENGTH]));
416            check_to_json(
417                key_transfer,
418                r#"{"cl_type":"Key","parsed":{"Transfer":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}}"#,
419            );
420
421            let key_deploy_info = Key::DeployInfo(DeployHash::new([5; DEPLOY_HASH_LENGTH]));
422            check_to_json(
423                key_deploy_info,
424                r#"{"cl_type":"Key","parsed":{"DeployInfo":"deploy-0505050505050505050505050505050505050505050505050505050505050505"}}"#,
425            );
426        }
427
428        #[test]
429        fn uref_cl_value_should_encode_to_json() {
430            let uref = URef::new([6; UREF_ADDR_LENGTH], AccessRights::READ_ADD_WRITE);
431            check_to_json(
432                uref,
433                r#"{"cl_type":"URef","parsed":"uref-0606060606060606060606060606060606060606060606060606060606060606-007"}"#,
434            );
435        }
436
437        #[test]
438        fn public_key_cl_value_should_encode_to_json() {
439            check_to_json(
440                PublicKey::from(
441                    &SecretKey::ed25519_from_bytes([7; SecretKey::ED25519_LENGTH]).unwrap(),
442                ),
443                r#"{"cl_type":"PublicKey","parsed":"01ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c"}"#,
444            );
445            check_to_json(
446                PublicKey::from(
447                    &SecretKey::secp256k1_from_bytes([8; SecretKey::SECP256K1_LENGTH]).unwrap(),
448                ),
449                r#"{"cl_type":"PublicKey","parsed":"0203f991f944d1e1954a7fc8b9bf62e0d78f015f4c07762d505e20e6c45260a3661b"}"#,
450            );
451        }
452    }
453
454    mod option {
455        use super::*;
456        use crate::crypto::SecretKey;
457
458        #[test]
459        fn bool_cl_value_should_encode_to_json() {
460            check_to_json(Some(true), r#"{"cl_type":{"Option":"Bool"},"parsed":true}"#);
461            check_to_json(
462                Some(false),
463                r#"{"cl_type":{"Option":"Bool"},"parsed":false}"#,
464            );
465            check_to_json(
466                Option::<bool>::None,
467                r#"{"cl_type":{"Option":"Bool"},"parsed":null}"#,
468            );
469        }
470
471        #[test]
472        fn i32_cl_value_should_encode_to_json() {
473            check_to_json(
474                Some(i32::min_value()),
475                r#"{"cl_type":{"Option":"I32"},"parsed":-2147483648}"#,
476            );
477            check_to_json(Some(0_i32), r#"{"cl_type":{"Option":"I32"},"parsed":0}"#);
478            check_to_json(
479                Some(i32::max_value()),
480                r#"{"cl_type":{"Option":"I32"},"parsed":2147483647}"#,
481            );
482            check_to_json(
483                Option::<i32>::None,
484                r#"{"cl_type":{"Option":"I32"},"parsed":null}"#,
485            );
486        }
487
488        #[test]
489        fn i64_cl_value_should_encode_to_json() {
490            check_to_json(
491                Some(i64::min_value()),
492                r#"{"cl_type":{"Option":"I64"},"parsed":-9223372036854775808}"#,
493            );
494            check_to_json(Some(0_i64), r#"{"cl_type":{"Option":"I64"},"parsed":0}"#);
495            check_to_json(
496                Some(i64::max_value()),
497                r#"{"cl_type":{"Option":"I64"},"parsed":9223372036854775807}"#,
498            );
499            check_to_json(
500                Option::<i64>::None,
501                r#"{"cl_type":{"Option":"I64"},"parsed":null}"#,
502            );
503        }
504
505        #[test]
506        fn u8_cl_value_should_encode_to_json() {
507            check_to_json(Some(0_u8), r#"{"cl_type":{"Option":"U8"},"parsed":0}"#);
508            check_to_json(
509                Some(u8::max_value()),
510                r#"{"cl_type":{"Option":"U8"},"parsed":255}"#,
511            );
512            check_to_json(
513                Option::<u8>::None,
514                r#"{"cl_type":{"Option":"U8"},"parsed":null}"#,
515            );
516        }
517
518        #[test]
519        fn u32_cl_value_should_encode_to_json() {
520            check_to_json(Some(0_u32), r#"{"cl_type":{"Option":"U32"},"parsed":0}"#);
521            check_to_json(
522                Some(u32::max_value()),
523                r#"{"cl_type":{"Option":"U32"},"parsed":4294967295}"#,
524            );
525            check_to_json(
526                Option::<u32>::None,
527                r#"{"cl_type":{"Option":"U32"},"parsed":null}"#,
528            );
529        }
530
531        #[test]
532        fn u64_cl_value_should_encode_to_json() {
533            check_to_json(Some(0_u64), r#"{"cl_type":{"Option":"U64"},"parsed":0}"#);
534            check_to_json(
535                Some(u64::max_value()),
536                r#"{"cl_type":{"Option":"U64"},"parsed":18446744073709551615}"#,
537            );
538            check_to_json(
539                Option::<u64>::None,
540                r#"{"cl_type":{"Option":"U64"},"parsed":null}"#,
541            );
542        }
543
544        #[test]
545        fn u128_cl_value_should_encode_to_json() {
546            check_to_json(
547                Some(U128::zero()),
548                r#"{"cl_type":{"Option":"U128"},"parsed":"0"}"#,
549            );
550            check_to_json(
551                Some(U128::max_value()),
552                r#"{"cl_type":{"Option":"U128"},"parsed":"340282366920938463463374607431768211455"}"#,
553            );
554            check_to_json(
555                Option::<U128>::None,
556                r#"{"cl_type":{"Option":"U128"},"parsed":null}"#,
557            );
558        }
559
560        #[test]
561        fn u256_cl_value_should_encode_to_json() {
562            check_to_json(
563                Some(U256::zero()),
564                r#"{"cl_type":{"Option":"U256"},"parsed":"0"}"#,
565            );
566            check_to_json(
567                Some(U256::max_value()),
568                r#"{"cl_type":{"Option":"U256"},"parsed":"115792089237316195423570985008687907853269984665640564039457584007913129639935"}"#,
569            );
570            check_to_json(
571                Option::<U256>::None,
572                r#"{"cl_type":{"Option":"U256"},"parsed":null}"#,
573            );
574        }
575
576        #[test]
577        fn u512_cl_value_should_encode_to_json() {
578            check_to_json(
579                Some(U512::zero()),
580                r#"{"cl_type":{"Option":"U512"},"parsed":"0"}"#,
581            );
582            check_to_json(
583                Some(U512::max_value()),
584                r#"{"cl_type":{"Option":"U512"},"parsed":"13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095"}"#,
585            );
586            check_to_json(
587                Option::<U512>::None,
588                r#"{"cl_type":{"Option":"U512"},"parsed":null}"#,
589            );
590        }
591
592        #[test]
593        fn unit_cl_value_should_encode_to_json() {
594            check_to_json(Some(()), r#"{"cl_type":{"Option":"Unit"},"parsed":null}"#);
595            check_to_json(
596                Option::<()>::None,
597                r#"{"cl_type":{"Option":"Unit"},"parsed":null}"#,
598            );
599        }
600
601        #[test]
602        fn string_cl_value_should_encode_to_json() {
603            check_to_json(
604                Some(String::new()),
605                r#"{"cl_type":{"Option":"String"},"parsed":""}"#,
606            );
607            check_to_json(
608                Some("test string".to_string()),
609                r#"{"cl_type":{"Option":"String"},"parsed":"test string"}"#,
610            );
611            check_to_json(
612                Option::<String>::None,
613                r#"{"cl_type":{"Option":"String"},"parsed":null}"#,
614            );
615        }
616
617        #[test]
618        fn key_cl_value_should_encode_to_json() {
619            let key_account = Key::Account(AccountHash::new([1; ACCOUNT_HASH_LENGTH]));
620            check_to_json(
621                Some(key_account),
622                r#"{"cl_type":{"Option":"Key"},"parsed":{"Account":"account-hash-0101010101010101010101010101010101010101010101010101010101010101"}}"#,
623            );
624
625            let key_hash = Key::Hash([2; KEY_HASH_LENGTH]);
626            check_to_json(
627                Some(key_hash),
628                r#"{"cl_type":{"Option":"Key"},"parsed":{"Hash":"hash-0202020202020202020202020202020202020202020202020202020202020202"}}"#,
629            );
630
631            let key_uref = Key::URef(URef::new([3; UREF_ADDR_LENGTH], AccessRights::READ));
632            check_to_json(
633                Some(key_uref),
634                r#"{"cl_type":{"Option":"Key"},"parsed":{"URef":"uref-0303030303030303030303030303030303030303030303030303030303030303-001"}}"#,
635            );
636
637            let key_transfer = Key::Transfer(TransferAddr::new([4; TRANSFER_ADDR_LENGTH]));
638            check_to_json(
639                Some(key_transfer),
640                r#"{"cl_type":{"Option":"Key"},"parsed":{"Transfer":"transfer-0404040404040404040404040404040404040404040404040404040404040404"}}"#,
641            );
642
643            let key_deploy_info = Key::DeployInfo(DeployHash::new([5; DEPLOY_HASH_LENGTH]));
644            check_to_json(
645                Some(key_deploy_info),
646                r#"{"cl_type":{"Option":"Key"},"parsed":{"DeployInfo":"deploy-0505050505050505050505050505050505050505050505050505050505050505"}}"#,
647            );
648
649            check_to_json(
650                Option::<Key>::None,
651                r#"{"cl_type":{"Option":"Key"},"parsed":null}"#,
652            )
653        }
654
655        #[test]
656        fn uref_cl_value_should_encode_to_json() {
657            let uref = URef::new([6; UREF_ADDR_LENGTH], AccessRights::READ_ADD_WRITE);
658            check_to_json(
659                Some(uref),
660                r#"{"cl_type":{"Option":"URef"},"parsed":"uref-0606060606060606060606060606060606060606060606060606060606060606-007"}"#,
661            );
662            check_to_json(
663                Option::<URef>::None,
664                r#"{"cl_type":{"Option":"URef"},"parsed":null}"#,
665            )
666        }
667
668        #[test]
669        fn public_key_cl_value_should_encode_to_json() {
670            check_to_json(
671                Some(PublicKey::from(
672                    &SecretKey::ed25519_from_bytes([7; SecretKey::ED25519_LENGTH]).unwrap(),
673                )),
674                r#"{"cl_type":{"Option":"PublicKey"},"parsed":"01ea4a6c63e29c520abef5507b132ec5f9954776aebebe7b92421eea691446d22c"}"#,
675            );
676            check_to_json(
677                Some(PublicKey::from(
678                    &SecretKey::secp256k1_from_bytes([8; SecretKey::SECP256K1_LENGTH]).unwrap(),
679                )),
680                r#"{"cl_type":{"Option":"PublicKey"},"parsed":"0203f991f944d1e1954a7fc8b9bf62e0d78f015f4c07762d505e20e6c45260a3661b"}"#,
681            );
682            check_to_json(
683                Option::<PublicKey>::None,
684                r#"{"cl_type":{"Option":"PublicKey"},"parsed":null}"#,
685            )
686        }
687    }
688
689    mod result {
690        use super::*;
691        use crate::crypto::SecretKey;
692
693        #[test]
694        fn bool_cl_value_should_encode_to_json() {
695            check_to_json(
696                Result::<bool, i32>::Ok(true),
697                r#"{"cl_type":{"Result":{"ok":"Bool","err":"I32"}},"parsed":{"Ok":true}}"#,
698            );
699            check_to_json(
700                Result::<bool, u32>::Ok(true),
701                r#"{"cl_type":{"Result":{"ok":"Bool","err":"U32"}},"parsed":{"Ok":true}}"#,
702            );
703            check_to_json(
704                Result::<bool, ()>::Ok(true),
705                r#"{"cl_type":{"Result":{"ok":"Bool","err":"Unit"}},"parsed":{"Ok":true}}"#,
706            );
707            check_to_json(
708                Result::<bool, String>::Ok(true),
709                r#"{"cl_type":{"Result":{"ok":"Bool","err":"String"}},"parsed":{"Ok":true}}"#,
710            );
711            check_to_json(
712                Result::<bool, i32>::Err(-1),
713                r#"{"cl_type":{"Result":{"ok":"Bool","err":"I32"}},"parsed":{"Err":-1}}"#,
714            );
715            check_to_json(
716                Result::<bool, u32>::Err(1),
717                r#"{"cl_type":{"Result":{"ok":"Bool","err":"U32"}},"parsed":{"Err":1}}"#,
718            );
719            check_to_json(
720                Result::<bool, ()>::Err(()),
721                r#"{"cl_type":{"Result":{"ok":"Bool","err":"Unit"}},"parsed":{"Err":null}}"#,
722            );
723            check_to_json(
724                Result::<bool, String>::Err("e".to_string()),
725                r#"{"cl_type":{"Result":{"ok":"Bool","err":"String"}},"parsed":{"Err":"e"}}"#,
726            );
727        }
728
729        #[test]
730        fn i32_cl_value_should_encode_to_json() {
731            check_to_json(
732                Result::<i32, i32>::Ok(-1),
733                r#"{"cl_type":{"Result":{"ok":"I32","err":"I32"}},"parsed":{"Ok":-1}}"#,
734            );
735            check_to_json(
736                Result::<i32, u32>::Ok(-1),
737                r#"{"cl_type":{"Result":{"ok":"I32","err":"U32"}},"parsed":{"Ok":-1}}"#,
738            );
739            check_to_json(
740                Result::<i32, ()>::Ok(-1),
741                r#"{"cl_type":{"Result":{"ok":"I32","err":"Unit"}},"parsed":{"Ok":-1}}"#,
742            );
743            check_to_json(
744                Result::<i32, String>::Ok(-1),
745                r#"{"cl_type":{"Result":{"ok":"I32","err":"String"}},"parsed":{"Ok":-1}}"#,
746            );
747            check_to_json(
748                Result::<i32, i32>::Err(-1),
749                r#"{"cl_type":{"Result":{"ok":"I32","err":"I32"}},"parsed":{"Err":-1}}"#,
750            );
751            check_to_json(
752                Result::<i32, u32>::Err(1),
753                r#"{"cl_type":{"Result":{"ok":"I32","err":"U32"}},"parsed":{"Err":1}}"#,
754            );
755            check_to_json(
756                Result::<i32, ()>::Err(()),
757                r#"{"cl_type":{"Result":{"ok":"I32","err":"Unit"}},"parsed":{"Err":null}}"#,
758            );
759            check_to_json(
760                Result::<i32, String>::Err("e".to_string()),
761                r#"{"cl_type":{"Result":{"ok":"I32","err":"String"}},"parsed":{"Err":"e"}}"#,
762            );
763        }
764
765        #[test]
766        fn i64_cl_value_should_encode_to_json() {
767            check_to_json(
768                Result::<i64, i32>::Ok(-1),
769                r#"{"cl_type":{"Result":{"ok":"I64","err":"I32"}},"parsed":{"Ok":-1}}"#,
770            );
771            check_to_json(
772                Result::<i64, u32>::Ok(-1),
773                r#"{"cl_type":{"Result":{"ok":"I64","err":"U32"}},"parsed":{"Ok":-1}}"#,
774            );
775            check_to_json(
776                Result::<i64, ()>::Ok(-1),
777                r#"{"cl_type":{"Result":{"ok":"I64","err":"Unit"}},"parsed":{"Ok":-1}}"#,
778            );
779            check_to_json(
780                Result::<i64, String>::Ok(-1),
781                r#"{"cl_type":{"Result":{"ok":"I64","err":"String"}},"parsed":{"Ok":-1}}"#,
782            );
783            check_to_json(
784                Result::<i64, i32>::Err(-1),
785                r#"{"cl_type":{"Result":{"ok":"I64","err":"I32"}},"parsed":{"Err":-1}}"#,
786            );
787            check_to_json(
788                Result::<i64, u32>::Err(1),
789                r#"{"cl_type":{"Result":{"ok":"I64","err":"U32"}},"parsed":{"Err":1}}"#,
790            );
791            check_to_json(
792                Result::<i64, ()>::Err(()),
793                r#"{"cl_type":{"Result":{"ok":"I64","err":"Unit"}},"parsed":{"Err":null}}"#,
794            );
795            check_to_json(
796                Result::<i64, String>::Err("e".to_string()),
797                r#"{"cl_type":{"Result":{"ok":"I64","err":"String"}},"parsed":{"Err":"e"}}"#,
798            );
799        }
800
801        #[test]
802        fn u8_cl_value_should_encode_to_json() {
803            check_to_json(
804                Result::<u8, i32>::Ok(1),
805                r#"{"cl_type":{"Result":{"ok":"U8","err":"I32"}},"parsed":{"Ok":1}}"#,
806            );
807            check_to_json(
808                Result::<u8, u32>::Ok(1),
809                r#"{"cl_type":{"Result":{"ok":"U8","err":"U32"}},"parsed":{"Ok":1}}"#,
810            );
811            check_to_json(
812                Result::<u8, ()>::Ok(1),
813                r#"{"cl_type":{"Result":{"ok":"U8","err":"Unit"}},"parsed":{"Ok":1}}"#,
814            );
815            check_to_json(
816                Result::<u8, String>::Ok(1),
817                r#"{"cl_type":{"Result":{"ok":"U8","err":"String"}},"parsed":{"Ok":1}}"#,
818            );
819            check_to_json(
820                Result::<u8, i32>::Err(-1),
821                r#"{"cl_type":{"Result":{"ok":"U8","err":"I32"}},"parsed":{"Err":-1}}"#,
822            );
823            check_to_json(
824                Result::<u8, u32>::Err(1),
825                r#"{"cl_type":{"Result":{"ok":"U8","err":"U32"}},"parsed":{"Err":1}}"#,
826            );
827            check_to_json(
828                Result::<u8, ()>::Err(()),
829                r#"{"cl_type":{"Result":{"ok":"U8","err":"Unit"}},"parsed":{"Err":null}}"#,
830            );
831            check_to_json(
832                Result::<u8, String>::Err("e".to_string()),
833                r#"{"cl_type":{"Result":{"ok":"U8","err":"String"}},"parsed":{"Err":"e"}}"#,
834            );
835        }
836
837        #[test]
838        fn u32_cl_value_should_encode_to_json() {
839            check_to_json(
840                Result::<u32, i32>::Ok(1),
841                r#"{"cl_type":{"Result":{"ok":"U32","err":"I32"}},"parsed":{"Ok":1}}"#,
842            );
843            check_to_json(
844                Result::<u32, u32>::Ok(1),
845                r#"{"cl_type":{"Result":{"ok":"U32","err":"U32"}},"parsed":{"Ok":1}}"#,
846            );
847            check_to_json(
848                Result::<u32, ()>::Ok(1),
849                r#"{"cl_type":{"Result":{"ok":"U32","err":"Unit"}},"parsed":{"Ok":1}}"#,
850            );
851            check_to_json(
852                Result::<u32, String>::Ok(1),
853                r#"{"cl_type":{"Result":{"ok":"U32","err":"String"}},"parsed":{"Ok":1}}"#,
854            );
855            check_to_json(
856                Result::<u32, i32>::Err(-1),
857                r#"{"cl_type":{"Result":{"ok":"U32","err":"I32"}},"parsed":{"Err":-1}}"#,
858            );
859            check_to_json(
860                Result::<u32, u32>::Err(1),
861                r#"{"cl_type":{"Result":{"ok":"U32","err":"U32"}},"parsed":{"Err":1}}"#,
862            );
863            check_to_json(
864                Result::<u32, ()>::Err(()),
865                r#"{"cl_type":{"Result":{"ok":"U32","err":"Unit"}},"parsed":{"Err":null}}"#,
866            );
867            check_to_json(
868                Result::<u32, String>::Err("e".to_string()),
869                r#"{"cl_type":{"Result":{"ok":"U32","err":"String"}},"parsed":{"Err":"e"}}"#,
870            );
871        }
872
873        #[test]
874        fn u64_cl_value_should_encode_to_json() {
875            check_to_json(
876                Result::<u64, i32>::Ok(1),
877                r#"{"cl_type":{"Result":{"ok":"U64","err":"I32"}},"parsed":{"Ok":1}}"#,
878            );
879            check_to_json(
880                Result::<u64, u32>::Ok(1),
881                r#"{"cl_type":{"Result":{"ok":"U64","err":"U32"}},"parsed":{"Ok":1}}"#,
882            );
883            check_to_json(
884                Result::<u64, ()>::Ok(1),
885                r#"{"cl_type":{"Result":{"ok":"U64","err":"Unit"}},"parsed":{"Ok":1}}"#,
886            );
887            check_to_json(
888                Result::<u64, String>::Ok(1),
889                r#"{"cl_type":{"Result":{"ok":"U64","err":"String"}},"parsed":{"Ok":1}}"#,
890            );
891            check_to_json(
892                Result::<u64, i32>::Err(-1),
893                r#"{"cl_type":{"Result":{"ok":"U64","err":"I32"}},"parsed":{"Err":-1}}"#,
894            );
895            check_to_json(
896                Result::<u64, u32>::Err(1),
897                r#"{"cl_type":{"Result":{"ok":"U64","err":"U32"}},"parsed":{"Err":1}}"#,
898            );
899            check_to_json(
900                Result::<u64, ()>::Err(()),
901                r#"{"cl_type":{"Result":{"ok":"U64","err":"Unit"}},"parsed":{"Err":null}}"#,
902            );
903            check_to_json(
904                Result::<u64, String>::Err("e".to_string()),
905                r#"{"cl_type":{"Result":{"ok":"U64","err":"String"}},"parsed":{"Err":"e"}}"#,
906            );
907        }
908
909        #[test]
910        fn u128_cl_value_should_encode_to_json() {
911            check_to_json(
912                Result::<U128, i32>::Ok(1.into()),
913                r#"{"cl_type":{"Result":{"ok":"U128","err":"I32"}},"parsed":{"Ok":"1"}}"#,
914            );
915            check_to_json(
916                Result::<U128, u32>::Ok(1.into()),
917                r#"{"cl_type":{"Result":{"ok":"U128","err":"U32"}},"parsed":{"Ok":"1"}}"#,
918            );
919            check_to_json(
920                Result::<U128, ()>::Ok(1.into()),
921                r#"{"cl_type":{"Result":{"ok":"U128","err":"Unit"}},"parsed":{"Ok":"1"}}"#,
922            );
923            check_to_json(
924                Result::<U128, String>::Ok(1.into()),
925                r#"{"cl_type":{"Result":{"ok":"U128","err":"String"}},"parsed":{"Ok":"1"}}"#,
926            );
927            check_to_json(
928                Result::<U128, i32>::Err(-1),
929                r#"{"cl_type":{"Result":{"ok":"U128","err":"I32"}},"parsed":{"Err":-1}}"#,
930            );
931            check_to_json(
932                Result::<U128, u32>::Err(1),
933                r#"{"cl_type":{"Result":{"ok":"U128","err":"U32"}},"parsed":{"Err":1}}"#,
934            );
935            check_to_json(
936                Result::<U128, ()>::Err(()),
937                r#"{"cl_type":{"Result":{"ok":"U128","err":"Unit"}},"parsed":{"Err":null}}"#,
938            );
939            check_to_json(
940                Result::<U128, String>::Err("e".to_string()),
941                r#"{"cl_type":{"Result":{"ok":"U128","err":"String"}},"parsed":{"Err":"e"}}"#,
942            );
943        }
944
945        #[test]
946        fn u256_cl_value_should_encode_to_json() {
947            check_to_json(
948                Result::<U256, i32>::Ok(1.into()),
949                r#"{"cl_type":{"Result":{"ok":"U256","err":"I32"}},"parsed":{"Ok":"1"}}"#,
950            );
951            check_to_json(
952                Result::<U256, u32>::Ok(1.into()),
953                r#"{"cl_type":{"Result":{"ok":"U256","err":"U32"}},"parsed":{"Ok":"1"}}"#,
954            );
955            check_to_json(
956                Result::<U256, ()>::Ok(1.into()),
957                r#"{"cl_type":{"Result":{"ok":"U256","err":"Unit"}},"parsed":{"Ok":"1"}}"#,
958            );
959            check_to_json(
960                Result::<U256, String>::Ok(1.into()),
961                r#"{"cl_type":{"Result":{"ok":"U256","err":"String"}},"parsed":{"Ok":"1"}}"#,
962            );
963            check_to_json(
964                Result::<U256, i32>::Err(-1),
965                r#"{"cl_type":{"Result":{"ok":"U256","err":"I32"}},"parsed":{"Err":-1}}"#,
966            );
967            check_to_json(
968                Result::<U256, u32>::Err(1),
969                r#"{"cl_type":{"Result":{"ok":"U256","err":"U32"}},"parsed":{"Err":1}}"#,
970            );
971            check_to_json(
972                Result::<U256, ()>::Err(()),
973                r#"{"cl_type":{"Result":{"ok":"U256","err":"Unit"}},"parsed":{"Err":null}}"#,
974            );
975            check_to_json(
976                Result::<U256, String>::Err("e".to_string()),
977                r#"{"cl_type":{"Result":{"ok":"U256","err":"String"}},"parsed":{"Err":"e"}}"#,
978            );
979        }
980
981        #[test]
982        fn u512_cl_value_should_encode_to_json() {
983            check_to_json(
984                Result::<U512, i32>::Ok(1.into()),
985                r#"{"cl_type":{"Result":{"ok":"U512","err":"I32"}},"parsed":{"Ok":"1"}}"#,
986            );
987            check_to_json(
988                Result::<U512, u32>::Ok(1.into()),
989                r#"{"cl_type":{"Result":{"ok":"U512","err":"U32"}},"parsed":{"Ok":"1"}}"#,
990            );
991            check_to_json(
992                Result::<U512, ()>::Ok(1.into()),
993                r#"{"cl_type":{"Result":{"ok":"U512","err":"Unit"}},"parsed":{"Ok":"1"}}"#,
994            );
995            check_to_json(
996                Result::<U512, String>::Ok(1.into()),
997                r#"{"cl_type":{"Result":{"ok":"U512","err":"String"}},"parsed":{"Ok":"1"}}"#,
998            );
999            check_to_json(
1000                Result::<U512, i32>::Err(-1),
1001                r#"{"cl_type":{"Result":{"ok":"U512","err":"I32"}},"parsed":{"Err":-1}}"#,
1002            );
1003            check_to_json(
1004                Result::<U512, u32>::Err(1),
1005                r#"{"cl_type":{"Result":{"ok":"U512","err":"U32"}},"parsed":{"Err":1}}"#,
1006            );
1007            check_to_json(
1008                Result::<U512, ()>::Err(()),
1009                r#"{"cl_type":{"Result":{"ok":"U512","err":"Unit"}},"parsed":{"Err":null}}"#,
1010            );
1011            check_to_json(
1012                Result::<U512, String>::Err("e".to_string()),
1013                r#"{"cl_type":{"Result":{"ok":"U512","err":"String"}},"parsed":{"Err":"e"}}"#,
1014            );
1015        }
1016
1017        #[test]
1018        fn unit_cl_value_should_encode_to_json() {
1019            check_to_json(
1020                Result::<(), i32>::Ok(()),
1021                r#"{"cl_type":{"Result":{"ok":"Unit","err":"I32"}},"parsed":{"Ok":null}}"#,
1022            );
1023            check_to_json(
1024                Result::<(), u32>::Ok(()),
1025                r#"{"cl_type":{"Result":{"ok":"Unit","err":"U32"}},"parsed":{"Ok":null}}"#,
1026            );
1027            check_to_json(
1028                Result::<(), ()>::Ok(()),
1029                r#"{"cl_type":{"Result":{"ok":"Unit","err":"Unit"}},"parsed":{"Ok":null}}"#,
1030            );
1031            check_to_json(
1032                Result::<(), String>::Ok(()),
1033                r#"{"cl_type":{"Result":{"ok":"Unit","err":"String"}},"parsed":{"Ok":null}}"#,
1034            );
1035            check_to_json(
1036                Result::<(), i32>::Err(-1),
1037                r#"{"cl_type":{"Result":{"ok":"Unit","err":"I32"}},"parsed":{"Err":-1}}"#,
1038            );
1039            check_to_json(
1040                Result::<(), u32>::Err(1),
1041                r#"{"cl_type":{"Result":{"ok":"Unit","err":"U32"}},"parsed":{"Err":1}}"#,
1042            );
1043            check_to_json(
1044                Result::<(), ()>::Err(()),
1045                r#"{"cl_type":{"Result":{"ok":"Unit","err":"Unit"}},"parsed":{"Err":null}}"#,
1046            );
1047            check_to_json(
1048                Result::<(), String>::Err("e".to_string()),
1049                r#"{"cl_type":{"Result":{"ok":"Unit","err":"String"}},"parsed":{"Err":"e"}}"#,
1050            );
1051        }
1052
1053        #[test]
1054        fn string_cl_value_should_encode_to_json() {
1055            check_to_json(
1056                Result::<String, i32>::Ok("test string".to_string()),
1057                r#"{"cl_type":{"Result":{"ok":"String","err":"I32"}},"parsed":{"Ok":"test string"}}"#,
1058            );
1059            check_to_json(
1060                Result::<String, u32>::Ok("test string".to_string()),
1061                r#"{"cl_type":{"Result":{"ok":"String","err":"U32"}},"parsed":{"Ok":"test string"}}"#,
1062            );
1063            check_to_json(
1064                Result::<String, ()>::Ok("test string".to_string()),
1065                r#"{"cl_type":{"Result":{"ok":"String","err":"Unit"}},"parsed":{"Ok":"test string"}}"#,
1066            );
1067            check_to_json(
1068                Result::<String, String>::Ok("test string".to_string()),
1069                r#"{"cl_type":{"Result":{"ok":"String","err":"String"}},"parsed":{"Ok":"test string"}}"#,
1070            );
1071            check_to_json(
1072                Result::<String, i32>::Err(-1),
1073                r#"{"cl_type":{"Result":{"ok":"String","err":"I32"}},"parsed":{"Err":-1}}"#,
1074            );
1075            check_to_json(
1076                Result::<String, u32>::Err(1),
1077                r#"{"cl_type":{"Result":{"ok":"String","err":"U32"}},"parsed":{"Err":1}}"#,
1078            );
1079            check_to_json(
1080                Result::<String, ()>::Err(()),
1081                r#"{"cl_type":{"Result":{"ok":"String","err":"Unit"}},"parsed":{"Err":null}}"#,
1082            );
1083            check_to_json(
1084                Result::<String, String>::Err("e".to_string()),
1085                r#"{"cl_type":{"Result":{"ok":"String","err":"String"}},"parsed":{"Err":"e"}}"#,
1086            );
1087        }
1088
1089        #[test]
1090        fn key_cl_value_should_encode_to_json() {
1091            let key = Key::Hash([2; KEY_HASH_LENGTH]);
1092            check_to_json(
1093                Result::<Key, i32>::Ok(key),
1094                r#"{"cl_type":{"Result":{"ok":"Key","err":"I32"}},"parsed":{"Ok":{"Hash":"hash-0202020202020202020202020202020202020202020202020202020202020202"}}}"#,
1095            );
1096            check_to_json(
1097                Result::<Key, u32>::Ok(key),
1098                r#"{"cl_type":{"Result":{"ok":"Key","err":"U32"}},"parsed":{"Ok":{"Hash":"hash-0202020202020202020202020202020202020202020202020202020202020202"}}}"#,
1099            );
1100            check_to_json(
1101                Result::<Key, ()>::Ok(key),
1102                r#"{"cl_type":{"Result":{"ok":"Key","err":"Unit"}},"parsed":{"Ok":{"Hash":"hash-0202020202020202020202020202020202020202020202020202020202020202"}}}"#,
1103            );
1104            check_to_json(
1105                Result::<Key, String>::Ok(key),
1106                r#"{"cl_type":{"Result":{"ok":"Key","err":"String"}},"parsed":{"Ok":{"Hash":"hash-0202020202020202020202020202020202020202020202020202020202020202"}}}"#,
1107            );
1108            check_to_json(
1109                Result::<Key, i32>::Err(-1),
1110                r#"{"cl_type":{"Result":{"ok":"Key","err":"I32"}},"parsed":{"Err":-1}}"#,
1111            );
1112            check_to_json(
1113                Result::<Key, u32>::Err(1),
1114                r#"{"cl_type":{"Result":{"ok":"Key","err":"U32"}},"parsed":{"Err":1}}"#,
1115            );
1116            check_to_json(
1117                Result::<Key, ()>::Err(()),
1118                r#"{"cl_type":{"Result":{"ok":"Key","err":"Unit"}},"parsed":{"Err":null}}"#,
1119            );
1120            check_to_json(
1121                Result::<Key, String>::Err("e".to_string()),
1122                r#"{"cl_type":{"Result":{"ok":"Key","err":"String"}},"parsed":{"Err":"e"}}"#,
1123            );
1124        }
1125
1126        #[test]
1127        fn uref_cl_value_should_encode_to_json() {
1128            let uref = URef::new([6; UREF_ADDR_LENGTH], AccessRights::READ_ADD_WRITE);
1129            check_to_json(
1130                Result::<URef, i32>::Ok(uref),
1131                r#"{"cl_type":{"Result":{"ok":"URef","err":"I32"}},"parsed":{"Ok":"uref-0606060606060606060606060606060606060606060606060606060606060606-007"}}"#,
1132            );
1133            check_to_json(
1134                Result::<URef, u32>::Ok(uref),
1135                r#"{"cl_type":{"Result":{"ok":"URef","err":"U32"}},"parsed":{"Ok":"uref-0606060606060606060606060606060606060606060606060606060606060606-007"}}"#,
1136            );
1137            check_to_json(
1138                Result::<URef, ()>::Ok(uref),
1139                r#"{"cl_type":{"Result":{"ok":"URef","err":"Unit"}},"parsed":{"Ok":"uref-0606060606060606060606060606060606060606060606060606060606060606-007"}}"#,
1140            );
1141            check_to_json(
1142                Result::<URef, String>::Ok(uref),
1143                r#"{"cl_type":{"Result":{"ok":"URef","err":"String"}},"parsed":{"Ok":"uref-0606060606060606060606060606060606060606060606060606060606060606-007"}}"#,
1144            );
1145            check_to_json(
1146                Result::<URef, i32>::Err(-1),
1147                r#"{"cl_type":{"Result":{"ok":"URef","err":"I32"}},"parsed":{"Err":-1}}"#,
1148            );
1149            check_to_json(
1150                Result::<URef, u32>::Err(1),
1151                r#"{"cl_type":{"Result":{"ok":"URef","err":"U32"}},"parsed":{"Err":1}}"#,
1152            );
1153            check_to_json(
1154                Result::<URef, ()>::Err(()),
1155                r#"{"cl_type":{"Result":{"ok":"URef","err":"Unit"}},"parsed":{"Err":null}}"#,
1156            );
1157            check_to_json(
1158                Result::<URef, String>::Err("e".to_string()),
1159                r#"{"cl_type":{"Result":{"ok":"URef","err":"String"}},"parsed":{"Err":"e"}}"#,
1160            );
1161        }
1162
1163        #[test]
1164        fn public_key_cl_value_should_encode_to_json() {
1165            let secret_key =
1166                SecretKey::secp256k1_from_bytes([8; SecretKey::SECP256K1_LENGTH]).unwrap();
1167            let public_key = PublicKey::from(&secret_key);
1168            check_to_json(
1169                Result::<PublicKey, i32>::Ok(public_key.clone()),
1170                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"I32"}},"parsed":{"Ok":"0203f991f944d1e1954a7fc8b9bf62e0d78f015f4c07762d505e20e6c45260a3661b"}}"#,
1171            );
1172            check_to_json(
1173                Result::<PublicKey, u32>::Ok(public_key.clone()),
1174                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"U32"}},"parsed":{"Ok":"0203f991f944d1e1954a7fc8b9bf62e0d78f015f4c07762d505e20e6c45260a3661b"}}"#,
1175            );
1176            check_to_json(
1177                Result::<PublicKey, ()>::Ok(public_key.clone()),
1178                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"Unit"}},"parsed":{"Ok":"0203f991f944d1e1954a7fc8b9bf62e0d78f015f4c07762d505e20e6c45260a3661b"}}"#,
1179            );
1180            check_to_json(
1181                Result::<PublicKey, String>::Ok(public_key),
1182                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"String"}},"parsed":{"Ok":"0203f991f944d1e1954a7fc8b9bf62e0d78f015f4c07762d505e20e6c45260a3661b"}}"#,
1183            );
1184            check_to_json(
1185                Result::<PublicKey, i32>::Err(-1),
1186                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"I32"}},"parsed":{"Err":-1}}"#,
1187            );
1188            check_to_json(
1189                Result::<PublicKey, u32>::Err(1),
1190                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"U32"}},"parsed":{"Err":1}}"#,
1191            );
1192            check_to_json(
1193                Result::<PublicKey, ()>::Err(()),
1194                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"Unit"}},"parsed":{"Err":null}}"#,
1195            );
1196            check_to_json(
1197                Result::<PublicKey, String>::Err("e".to_string()),
1198                r#"{"cl_type":{"Result":{"ok":"PublicKey","err":"String"}},"parsed":{"Err":"e"}}"#,
1199            );
1200        }
1201    }
1202}