kore_contract_sdk/
value_wrapper.rs1use std::io::{Read, Write};
5
6use borsh::{BorshDeserialize, BorshSerialize};
7use serde::{Deserialize, Serialize};
8use serde_json::{Map, Number, Value};
9
10#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]
12pub struct ValueWrapper(pub Value);
13
14impl BorshSerialize for ValueWrapper {
16 #[inline]
17 fn serialize<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
18 match &self.0 {
19 Value::Bool(data) => {
20 BorshSerialize::serialize(&0u8, writer)?;
21 BorshSerialize::serialize(&data, writer)
22 }
23 Value::Number(data) => {
24 BorshSerialize::serialize(&1u8, writer)?;
25 'data: {
26 if data.is_f64() {
27 let Some(data) = data.as_f64() else {
28 break 'data;
29 };
30 BorshSerialize::serialize(&0u8, writer)?;
31 return BorshSerialize::serialize(&data, writer);
32 } else if data.is_i64() {
33 let Some(data) = data.as_i64() else {
34 break 'data;
35 };
36 BorshSerialize::serialize(&1u8, writer)?;
37 return BorshSerialize::serialize(&data, writer);
38 } else if data.is_u64() {
39 let Some(data) = data.as_u64() else {
40 break 'data;
41 };
42 BorshSerialize::serialize(&2u8, writer)?;
43 return BorshSerialize::serialize(&data, writer);
44 }
45 }
46 Err(std::io::Error::new(
47 std::io::ErrorKind::InvalidData,
48 "Invalid number type",
49 ))
50 }
51 Value::String(data) => {
52 BorshSerialize::serialize(&2u8, writer)?;
53 BorshSerialize::serialize(&data, writer)
54 }
55 Value::Array(data) => {
56 BorshSerialize::serialize(&3u8, writer)?;
57 BorshSerialize::serialize(&(data.len() as u32), writer)?;
58 for element in data {
59 let element = ValueWrapper(element.to_owned());
60 BorshSerialize::serialize(&element, writer)?;
61 }
62 Ok(())
63 }
64 Value::Object(data) => {
65 BorshSerialize::serialize(&4u8, writer)?;
66 BorshSerialize::serialize(&(data.len() as u32), writer)?;
67 for (key, value) in data {
68 BorshSerialize::serialize(&key, writer)?;
69 let value = ValueWrapper(value.to_owned());
70 BorshSerialize::serialize(&value, writer)?;
71 }
72 Ok(())
73 }
74 Value::Null => BorshSerialize::serialize(&5u8, writer),
75 }
76 }
77}
78
79impl BorshDeserialize for ValueWrapper {
81 #[inline]
82 fn deserialize_reader<R: Read>(reader: &mut R) -> std::io::Result<Self> {
83 let order: u8 = BorshDeserialize::deserialize_reader(reader)?;
84 match order {
85 0 => {
86 let data: bool = BorshDeserialize::deserialize_reader(reader)?;
87 Ok(ValueWrapper(Value::Bool(data)))
88 }
89 1 => {
90 let internal_order: u8 =
91 BorshDeserialize::deserialize_reader(reader)?;
92 match internal_order {
93 0 => {
94 let data: f64 =
95 BorshDeserialize::deserialize_reader(reader)?;
96 let Some(data_f64) = Number::from_f64(data) else {
97 return Err(std::io::Error::new(
98 std::io::ErrorKind::InvalidInput,
99 format!("Invalid f64 Number: {}", data),
100 ));
101 };
102 Ok(ValueWrapper(Value::Number(data_f64)))
103 }
104 1 => {
105 let data: i64 =
106 BorshDeserialize::deserialize_reader(reader)?;
107 Ok(ValueWrapper(Value::Number(Number::from(data))))
108 }
109 2 => {
110 let data: u64 =
111 BorshDeserialize::deserialize_reader(reader)?;
112 Ok(ValueWrapper(Value::Number(Number::from(data))))
113 }
114 _ => Err(std::io::Error::new(
115 std::io::ErrorKind::InvalidInput,
116 format!(
117 "Invalid Number representation: {}",
118 internal_order
119 ),
120 )),
121 }
122 }
123 2 => {
124 let data: String =
125 BorshDeserialize::deserialize_reader(reader)?;
126 Ok(ValueWrapper(Value::String(data)))
127 }
128 3 => {
129 let len = u32::deserialize_reader(reader)?;
130 if len == 0 {
131 Ok(ValueWrapper(Value::Array(Vec::new())))
132 } else {
133 let mut result = Vec::with_capacity(len as usize);
134 for _ in 0..len {
135 result
136 .push(ValueWrapper::deserialize_reader(reader)?.0);
137 }
138 Ok(ValueWrapper(Value::Array(result)))
139 }
140 }
141 4 => {
142 let len = u32::deserialize_reader(reader)?;
143 let mut result = Map::new();
144 for _ in 0..len {
145 let key = String::deserialize_reader(reader)?;
146 let value = ValueWrapper::deserialize_reader(reader)?;
147 result.insert(key, value.0);
148 }
149 Ok(ValueWrapper(Value::Object(result)))
150 }
151 5 => Ok(ValueWrapper(Value::Null)),
152 _ => Err(std::io::Error::new(
153 std::io::ErrorKind::InvalidInput,
154 format!("Invalid Value representation: {}", order),
155 )),
156 }
157 }
158}
159#[cfg(test)]
160mod tests {
161 use super::*;
162
163 #[test]
164 fn test_value_wrapper() {
165 let value = ValueWrapper(Value::String("test".to_owned()));
166 let vec = borsh::to_vec(&value).unwrap();
167 let value2: ValueWrapper = BorshDeserialize::try_from_slice(&vec).unwrap();
168 assert_eq!(value, value2);
169 }
170}