casper_event_standard/
cl_type2.rs

1use alloc::{boxed::Box, vec::Vec};
2use casper_types::{
3    bytesrepr::{self, FromBytes, ToBytes},
4    CLType, CLTyped,
5};
6
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10/// A wrapper on top of [`CLType`].
11///
12/// It is required as the original [`CLType`] doesn't implement [`CLTyped`],
13/// [`FromBytes`] and [`ToBytes`].
14///
15/// It can be removed if this [`issue`] is resolved.
16///
17/// [`CLType`]: casper_types::CLType
18/// [`CLTyped`]: casper_types::CLTyped
19/// [`FromBytes`]: casper_types::bytesrepr::FromBytes
20/// [`ToBytes`]: casper_types::bytesrepr::ToBytes
21/// [`issue`]: https://github.com/casper-network/casper-node/issues/3593
22#[derive(PartialEq, Debug, Clone)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24pub struct CLType2(pub CLType);
25
26impl CLType2 {
27    /// Turn it into original [`CLType`]: casper_types::CLType.
28    pub fn downcast(self) -> CLType {
29        self.0
30    }
31}
32
33impl CLTyped for CLType2 {
34    fn cl_type() -> CLType {
35        CLType::Any
36    }
37}
38
39impl ToBytes for CLType2 {
40    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
41        let mut result = Vec::new();
42        append_bytes(&self.0, &mut result)?;
43        Ok(result)
44    }
45
46    fn serialized_length(&self) -> usize {
47        self.0.serialized_length()
48    }
49}
50
51impl FromBytes for CLType2 {
52    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
53        CLType::from_bytes(bytes).map(|(cl_type, bytes)| (CLType2(cl_type), bytes))
54    }
55}
56
57const CL_TYPE_TAG_BOOL: u8 = 0;
58const CL_TYPE_TAG_I32: u8 = 1;
59const CL_TYPE_TAG_I64: u8 = 2;
60const CL_TYPE_TAG_U8: u8 = 3;
61const CL_TYPE_TAG_U32: u8 = 4;
62const CL_TYPE_TAG_U64: u8 = 5;
63const CL_TYPE_TAG_U128: u8 = 6;
64const CL_TYPE_TAG_U256: u8 = 7;
65const CL_TYPE_TAG_U512: u8 = 8;
66const CL_TYPE_TAG_UNIT: u8 = 9;
67const CL_TYPE_TAG_STRING: u8 = 10;
68const CL_TYPE_TAG_KEY: u8 = 11;
69const CL_TYPE_TAG_UREF: u8 = 12;
70const CL_TYPE_TAG_OPTION: u8 = 13;
71const CL_TYPE_TAG_LIST: u8 = 14;
72const CL_TYPE_TAG_BYTE_ARRAY: u8 = 15;
73const CL_TYPE_TAG_RESULT: u8 = 16;
74const CL_TYPE_TAG_MAP: u8 = 17;
75const CL_TYPE_TAG_TUPLE1: u8 = 18;
76const CL_TYPE_TAG_TUPLE2: u8 = 19;
77const CL_TYPE_TAG_TUPLE3: u8 = 20;
78const CL_TYPE_TAG_ANY: u8 = 21;
79const CL_TYPE_TAG_PUBLIC_KEY: u8 = 22;
80
81fn append_bytes(cl_type: &CLType, stream: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
82    match cl_type {
83        CLType::Bool => stream.push(CL_TYPE_TAG_BOOL),
84        CLType::I32 => stream.push(CL_TYPE_TAG_I32),
85        CLType::I64 => stream.push(CL_TYPE_TAG_I64),
86        CLType::U8 => stream.push(CL_TYPE_TAG_U8),
87        CLType::U32 => stream.push(CL_TYPE_TAG_U32),
88        CLType::U64 => stream.push(CL_TYPE_TAG_U64),
89        CLType::U128 => stream.push(CL_TYPE_TAG_U128),
90        CLType::U256 => stream.push(CL_TYPE_TAG_U256),
91        CLType::U512 => stream.push(CL_TYPE_TAG_U512),
92        CLType::Unit => stream.push(CL_TYPE_TAG_UNIT),
93        CLType::String => stream.push(CL_TYPE_TAG_STRING),
94        CLType::Key => stream.push(CL_TYPE_TAG_KEY),
95        CLType::URef => stream.push(CL_TYPE_TAG_UREF),
96        CLType::PublicKey => stream.push(CL_TYPE_TAG_PUBLIC_KEY),
97        CLType::Option(cl_type) => {
98            stream.push(CL_TYPE_TAG_OPTION);
99            append_bytes(cl_type, stream)?;
100        }
101        CLType::List(cl_type) => {
102            stream.push(CL_TYPE_TAG_LIST);
103            append_bytes(cl_type, stream)?;
104        }
105        CLType::ByteArray(len) => {
106            stream.push(CL_TYPE_TAG_BYTE_ARRAY);
107            stream.append(&mut len.to_bytes()?);
108        }
109        CLType::Result { ok, err } => {
110            stream.push(CL_TYPE_TAG_RESULT);
111            append_bytes(ok, stream)?;
112            append_bytes(err, stream)?;
113        }
114        CLType::Map { key, value } => {
115            stream.push(CL_TYPE_TAG_MAP);
116            append_bytes(key, stream)?;
117            append_bytes(value, stream)?;
118        }
119        CLType::Tuple1(cl_type_array) => {
120            serialize_cl_tuple_type(CL_TYPE_TAG_TUPLE1, cl_type_array, stream)?
121        }
122        CLType::Tuple2(cl_type_array) => {
123            serialize_cl_tuple_type(CL_TYPE_TAG_TUPLE2, cl_type_array, stream)?
124        }
125        CLType::Tuple3(cl_type_array) => {
126            serialize_cl_tuple_type(CL_TYPE_TAG_TUPLE3, cl_type_array, stream)?
127        }
128        CLType::Any => stream.push(CL_TYPE_TAG_ANY),
129    }
130    Ok(())
131}
132
133fn serialize_cl_tuple_type<'a, T: IntoIterator<Item = &'a Box<CLType>>>(
134    tag: u8,
135    cl_type_array: T,
136    stream: &mut Vec<u8>,
137) -> Result<(), bytesrepr::Error> {
138    stream.push(tag);
139    for cl_type in cl_type_array {
140        append_bytes(cl_type, stream)?;
141    }
142    Ok(())
143}
144
145// TODO: Tests