1use crate::{
18 assert_not_shortened_hex,
19 AccountId32,
20 Hex,
21 Value,
22};
23use anyhow::{
24 Context,
25 Result,
26};
27use primitive_types::U128;
28use scale::{
29 Decode,
30 Encode,
31 Output,
32};
33use scale_info::{
34 form::PortableForm,
35 IntoPortable,
36 Path,
37 TypeInfo,
38};
39use std::{
40 boxed::Box,
41 collections::HashMap,
42 convert::TryFrom,
43 str::FromStr,
44};
45
46#[derive(Default)]
48pub struct EnvTypesTranscoder {
49 encoders: HashMap<u32, Box<dyn CustomTypeEncoder>>,
50 decoders: HashMap<u32, Box<dyn CustomTypeDecoder>>,
51}
52
53impl EnvTypesTranscoder {
54 pub fn new(
56 encoders: HashMap<u32, Box<dyn CustomTypeEncoder>>,
57 decoders: HashMap<u32, Box<dyn CustomTypeDecoder>>,
58 ) -> Self {
59 Self { encoders, decoders }
60 }
61
62 pub fn try_encode<O>(
69 &self,
70 type_id: u32,
71 value: &Value,
72 output: &mut O,
73 ) -> Result<bool>
74 where
75 O: Output,
76 {
77 match self.encoders.get(&type_id) {
78 Some(encoder) => {
79 tracing::debug!("Encoding type {:?} with custom encoder", type_id);
80 let encoded_env_type = encoder
81 .encode_value(value)
82 .context("Error encoding custom type")?;
83 output.write(&encoded_env_type);
84 Ok(true)
85 }
86 None => Ok(false),
87 }
88 }
89
90 pub fn try_decode(&self, type_id: u32, input: &mut &[u8]) -> Result<Option<Value>> {
98 match self.decoders.get(&type_id) {
99 Some(decoder) => {
100 tracing::debug!("Decoding type {:?} with custom decoder", type_id);
101 let decoded = decoder.decode_value(input)?;
102 Ok(Some(decoded))
103 }
104 None => {
105 tracing::debug!("No custom decoder found for type {:?}", type_id);
106 Ok(None)
107 }
108 }
109 }
110}
111
112#[derive(Clone, Debug, Eq, PartialEq, Hash)]
113pub struct PathKey(Vec<String>);
114
115impl PathKey {
116 pub fn from_type<T>() -> Self
117 where
118 T: TypeInfo,
119 {
120 let type_info = T::type_info();
121 let path = type_info.path.into_portable(&mut Default::default());
122 PathKey::from(&path)
123 }
124}
125
126impl From<&Path<PortableForm>> for PathKey {
127 fn from(path: &Path<PortableForm>) -> Self {
128 PathKey(path.segments.to_vec())
129 }
130}
131
132pub type TypesByPath = HashMap<PathKey, u32>;
133
134pub trait CustomTypeEncoder: Send + Sync {
137 fn encode_value(&self, value: &Value) -> Result<Vec<u8>>;
138}
139
140pub trait CustomTypeDecoder: Send + Sync {
143 fn decode_value(&self, input: &mut &[u8]) -> Result<Value>;
144}
145
146#[derive(Clone)]
151pub struct AccountId;
152
153impl CustomTypeEncoder for AccountId {
154 fn encode_value(&self, value: &Value) -> Result<Vec<u8>> {
155 let account_id = match value {
156 Value::Literal(literal) => {
157 AccountId32::from_str(literal).map_err(|e| {
158 anyhow::anyhow!(
159 "Error parsing AccountId from literal `{}`: {}",
160 literal,
161 e
162 )
163 })?
164 }
165 Value::String(string) => {
166 AccountId32::from_str(string).map_err(|e| {
167 anyhow::anyhow!(
168 "Error parsing AccountId from string '{}': {}",
169 string,
170 e
171 )
172 })?
173 }
174 Value::Hex(hex) => {
175 AccountId32::try_from(hex.bytes()).map_err(|_| {
176 anyhow::anyhow!(
177 "Error converting hex bytes `{:?}` to AccountId",
178 hex.bytes()
179 )
180 })?
181 }
182 _ => {
183 return Err(anyhow::anyhow!(
184 "Expected a string, literal, or hex for an AccountId"
185 ))
186 }
187 };
188 Ok(account_id.encode())
189 }
190}
191
192impl CustomTypeDecoder for AccountId {
193 fn decode_value(&self, input: &mut &[u8]) -> Result<Value> {
194 let account_id = AccountId32::decode(input)?;
195 Ok(Value::Literal(account_id.to_ss58check()))
196 }
197}
198
199#[derive(Clone)]
202pub struct Hash;
203
204impl CustomTypeEncoder for Hash {
205 fn encode_value(&self, value: &Value) -> Result<Vec<u8>> {
206 let h256 = match value {
208 Value::Literal(literal) => {
209 primitive_types::H256::from_str(literal).map_err(|e| {
210 anyhow::anyhow!(
211 "Error parsing H256 from literal `{}`: {}",
212 literal,
213 e
214 )
215 })?
216 }
217 Value::String(string) => {
218 primitive_types::H256::from_str(string).map_err(|e| {
219 anyhow::anyhow!("Error parsing H256 from string '{}': {}", string, e)
220 })?
221 }
222 Value::Hex(hex) => primitive_types::H256::from_slice(hex.bytes()),
223 _ => {
224 return Err(anyhow::anyhow!(
225 "Expected a string, hex, uint, or literal for a U256"
226 ))
227 }
228 };
229 Ok(h256.encode())
230 }
231}
232
233impl CustomTypeDecoder for Hash {
234 fn decode_value(&self, input: &mut &[u8]) -> Result<Value> {
235 let hash = primitive_types::H256::decode(input)?;
236 Ok(Value::Hex(Hex::from_str(&format!("{hash:?}"))?))
237 }
238}
239
240#[derive(Clone)]
243pub struct H160;
244
245impl CustomTypeDecoder for H160 {
246 fn decode_value(&self, input: &mut &[u8]) -> Result<Value> {
247 let h160 = primitive_types::H160::decode(input)?;
248 Ok(Value::Hex(Hex::from_str(&format!("{h160:?}"))?))
249 }
250}
251
252impl CustomTypeEncoder for H160 {
253 fn encode_value(&self, value: &Value) -> Result<Vec<u8>> {
254 let h160 = match value {
255 Value::Literal(literal) => {
256 primitive_types::H160::from_str(literal).map_err(|e| {
257 anyhow::anyhow!(
258 "Error parsing H160 from literal `{}`: {}",
259 literal,
260 e
261 )
262 })?
263 }
264 Value::String(string) => {
265 assert_not_shortened_hex(string);
266 primitive_types::H160::from_str(string).map_err(|e| {
267 anyhow::anyhow!("Error parsing H160 from string '{}': {}", string, e)
268 })?
269 }
270 Value::Hex(hex) => primitive_types::H160::from_slice(hex.bytes()),
271 _ => {
272 return Err(anyhow::anyhow!(
273 "Expected a string, literal, or hex for an H160"
274 ))
275 }
276 };
277 Ok(h160.encode())
278 }
279}
280
281#[derive(Clone)]
284pub struct U256;
285
286impl CustomTypeDecoder for U256 {
287 fn decode_value(&self, input: &mut &[u8]) -> Result<Value> {
288 let u256 = primitive_types::U256::decode(input)?;
289 Ok(Value::Literal(format!("{}", u256)))
290 }
291}
292
293impl CustomTypeEncoder for U256 {
294 fn encode_value(&self, value: &Value) -> Result<Vec<u8>> {
295 let u256 = match value {
296 Value::Literal(literal) => {
297 primitive_types::U256::from_str(literal).map_err(|e| {
298 anyhow::anyhow!(
299 "Error parsing U256 from literal `{}`: {}",
300 literal,
301 e
302 )
303 })?
304 }
305 Value::String(string) => {
306 primitive_types::U256::from_str(string).map_err(|e| {
307 anyhow::anyhow!("Error parsing U256 from string '{}': {}", string, e)
308 })?
309 }
310 Value::UInt(uint128) => {
311 let u_128 = U128::from(*uint128);
312 primitive_types::U256::from(u_128)
313 }
314 Value::Hex(hex) => primitive_types::U256::from_little_endian(hex.bytes()),
316 _ => {
317 return Err(anyhow::anyhow!(
318 "Expected a string, hex, uint, or literal for a U256"
319 ))
320 }
321 };
322 let ret = u256.encode();
323 Ok(ret)
324 }
325}
326
327#[derive(Clone)]
330pub struct H256;
331
332impl CustomTypeDecoder for H256 {
333 fn decode_value(&self, input: &mut &[u8]) -> Result<Value> {
334 let h256 = primitive_types::H256::decode(input)?;
335 Ok(Value::Hex(Hex::from_str(&format!("{h256:?}"))?))
336 }
337}
338
339impl CustomTypeEncoder for H256 {
340 fn encode_value(&self, value: &Value) -> Result<Vec<u8>> {
341 let h256 = match value {
342 Value::Literal(literal) => {
343 primitive_types::H256::from_str(literal).map_err(|e| {
344 anyhow::anyhow!(
345 "Error parsing H256 from literal `{}`: {}",
346 literal,
347 e
348 )
349 })?
350 }
351 Value::String(string) => {
352 primitive_types::H256::from_str(string).map_err(|e| {
353 anyhow::anyhow!("Error parsing H256 from string '{}': {}", string, e)
354 })?
355 }
356 Value::Hex(hex) => primitive_types::H256::from_slice(hex.bytes()),
357 _ => {
358 return Err(anyhow::anyhow!(
359 "Expected a string, hex, uint, or literal for a H256"
360 ))
361 }
362 };
363 Ok(h256.encode())
364 }
365}
366
367