casper_types/
cl_value.rs

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