referrerpolicy=no-referrer-when-downgrade

pallet_revive/evm/api/
hex_serde.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18use alloc::{format, string::String, vec::Vec};
19use alloy_core::hex;
20use serde::{Deserialize, Deserializer, Serializer};
21
22pub trait HexCodec: Sized {
23	type Error;
24	fn to_hex(&self) -> String;
25	fn from_hex(s: String) -> Result<Self, Self::Error>;
26}
27
28macro_rules! impl_hex_codec {
29    ($($t:ty),*) => {
30        $(
31            impl HexCodec for $t {
32                type Error = core::num::ParseIntError;
33                fn to_hex(&self) -> String {
34                    format!("0x{:x}", self)
35                }
36                fn from_hex(s: String) -> Result<Self, Self::Error> {
37                    <$t>::from_str_radix(s.trim_start_matches("0x"), 16)
38                }
39            }
40        )*
41    };
42}
43
44impl_hex_codec!(u8, u32);
45
46impl<const T: usize> HexCodec for [u8; T] {
47	type Error = hex::FromHexError;
48	fn to_hex(&self) -> String {
49		format!("0x{}", hex::encode(self))
50	}
51	fn from_hex(s: String) -> Result<Self, Self::Error> {
52		let data = hex::decode(s.trim_start_matches("0x"))?;
53		data.try_into().map_err(|_| hex::FromHexError::InvalidStringLength)
54	}
55}
56
57impl HexCodec for Vec<u8> {
58	type Error = hex::FromHexError;
59	fn to_hex(&self) -> String {
60		format!("0x{}", hex::encode(self))
61	}
62	fn from_hex(s: String) -> Result<Self, Self::Error> {
63		hex::decode(s.trim_start_matches("0x"))
64	}
65}
66
67pub fn serialize<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
68where
69	S: Serializer,
70	T: HexCodec,
71{
72	let s = value.to_hex();
73	serializer.serialize_str(&s)
74}
75
76pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
77where
78	D: Deserializer<'de>,
79	T: HexCodec,
80	<T as HexCodec>::Error: core::fmt::Debug,
81{
82	let s = String::deserialize(deserializer)?;
83	let value = T::from_hex(s).map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?;
84	Ok(value)
85}