1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use alloc::vec::Vec;
use crate::{
bytesrepr::{self, FromBytes, ToBytes, U32_SERIALIZED_LENGTH},
CLType, CLTyped,
};
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct CLTypeMismatch {
pub expected: CLType,
pub found: CLType,
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum CLValueError {
Serialization(bytesrepr::Error),
Type(CLTypeMismatch),
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct CLValue {
cl_type: CLType,
bytes: Vec<u8>,
}
impl CLValue {
pub fn from_t<T: CLTyped + ToBytes>(t: T) -> Result<CLValue, CLValueError> {
let bytes = t.into_bytes().map_err(CLValueError::Serialization)?;
Ok(CLValue {
cl_type: T::cl_type(),
bytes,
})
}
pub fn into_t<T: CLTyped + FromBytes>(self) -> Result<T, CLValueError> {
let expected = T::cl_type();
if self.cl_type == expected {
bytesrepr::deserialize(self.bytes).map_err(CLValueError::Serialization)
} else {
Err(CLValueError::Type(CLTypeMismatch {
expected,
found: self.cl_type,
}))
}
}
#[doc(hidden)]
pub fn from_components(cl_type: CLType, bytes: Vec<u8>) -> Self {
Self { cl_type, bytes }
}
#[doc(hidden)]
pub fn destructure(self) -> (CLType, Vec<u8>) {
(self.cl_type, self.bytes)
}
pub fn cl_type(&self) -> &CLType {
&self.cl_type
}
pub fn inner_bytes(&self) -> &Vec<u8> {
&self.bytes
}
pub fn serialized_length(&self) -> usize {
self.cl_type.serialized_length() + U32_SERIALIZED_LENGTH + self.bytes.len()
}
}
impl ToBytes for CLValue {
fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
self.clone().into_bytes()
}
fn into_bytes(self) -> Result<Vec<u8>, bytesrepr::Error> {
let mut result = self.bytes.into_bytes()?;
self.cl_type.append_bytes(&mut result);
Ok(result)
}
fn serialized_length(&self) -> usize {
self.bytes.serialized_length() + self.cl_type.serialized_length()
}
}
impl FromBytes for CLValue {
fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
let (bytes, remainder) = Vec::<u8>::from_bytes(bytes)?;
let (cl_type, remainder) = CLType::from_bytes(remainder)?;
let cl_value = CLValue { cl_type, bytes };
Ok((cl_value, remainder))
}
}