referrerpolicy=no-referrer-when-downgrade

pallet_revive/evm/api/
byte.rs

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
// This file is part of Substrate.

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// 	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Define Byte wrapper types for encoding and decoding hex strings

use super::hex_serde::HexCodec;
use alloc::{vec, vec::Vec};
use alloy_core::hex;
use codec::{Decode, Encode};
use core::{
	fmt::{Debug, Display, Formatter, Result as FmtResult},
	str::FromStr,
};
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};

impl FromStr for Bytes {
	type Err = hex::FromHexError;
	fn from_str(s: &str) -> Result<Self, Self::Err> {
		let data = hex::decode(s.trim_start_matches("0x"))?;
		Ok(Bytes(data))
	}
}

macro_rules! impl_hex {
    ($type:ident, $inner:ty, $default:expr) => {
        #[derive(Encode, Decode, Eq, PartialEq, TypeInfo, Clone, Serialize, Deserialize)]
        #[doc = concat!("`", stringify!($inner), "`", " wrapper type for encoding and decoding hex strings")]
        pub struct $type(#[serde(with = "crate::evm::api::hex_serde")] pub $inner);

        impl Default for $type {
            fn default() -> Self {
                $type($default)
            }
        }

        impl From<$inner> for $type {
            fn from(inner: $inner) -> Self {
                $type(inner)
            }
        }

        impl Debug for $type {
            fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
				let hex_str = self.0.to_hex();
				let truncated = &hex_str[..hex_str.len().min(100)];
				let ellipsis = if hex_str.len() > 100 { "..." } else { "" };
                write!(f, concat!(stringify!($type), "({}{})"), truncated,ellipsis)
            }
        }

        impl Display for $type {
            fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
                write!(f, "{}", self.0.to_hex())
            }
        }
    };
}

impl Bytes {
	/// See `Vec::is_empty`
	pub fn is_empty(&self) -> bool {
		self.0.is_empty()
	}
}

impl_hex!(Byte, u8, 0u8);
impl_hex!(Bytes, Vec<u8>, vec![]);
impl_hex!(Bytes8, [u8; 8], [0u8; 8]);
impl_hex!(Bytes256, [u8; 256], [0u8; 256]);

#[test]
fn serialize_works() {
	let a = Byte(42);
	let s = serde_json::to_string(&a).unwrap();
	assert_eq!(s, "\"0x2a\"");
	let b = serde_json::from_str::<Byte>(&s).unwrap();
	assert_eq!(a, b);

	let a = Bytes(b"bello world".to_vec());
	let s = serde_json::to_string(&a).unwrap();
	assert_eq!(s, "\"0x62656c6c6f20776f726c64\"");
	let b = serde_json::from_str::<Bytes>(&s).unwrap();
	assert_eq!(a, b);

	let a = Bytes256([42u8; 256]);
	let s = serde_json::to_string(&a).unwrap();
	let b = serde_json::from_str::<Bytes256>(&s).unwrap();
	assert_eq!(a, b);
}