pallet_revive/evm/api/
byte.rs1use super::hex_serde::HexCodec;
20use alloc::{vec, vec::Vec};
21use alloy_core::hex;
22use codec::{Decode, DecodeWithMemTracking, Encode};
23use core::{
24 fmt::{Debug, Display, Formatter, Result as FmtResult},
25 str::FromStr,
26};
27use scale_info::TypeInfo;
28use serde::{Deserialize, Serialize};
29
30impl FromStr for Bytes {
31 type Err = hex::FromHexError;
32 fn from_str(s: &str) -> Result<Self, Self::Err> {
33 let data = hex::decode(s.trim_start_matches("0x"))?;
34 Ok(Bytes(data))
35 }
36}
37
38macro_rules! impl_hex {
39 ($type:ident, $inner:ty, $default:expr) => {
40 #[derive(Encode, Decode, Eq, PartialEq, Ord, PartialOrd, TypeInfo, Clone, Serialize, Deserialize, Hash, DecodeWithMemTracking)]
41 #[doc = concat!("`", stringify!($inner), "`", " wrapper type for encoding and decoding hex strings")]
42 pub struct $type(#[serde(with = "crate::evm::api::hex_serde")] pub $inner);
43
44 impl Default for $type {
45 fn default() -> Self {
46 $type($default)
47 }
48 }
49
50 impl From<$inner> for $type {
51 fn from(inner: $inner) -> Self {
52 $type(inner)
53 }
54 }
55
56 impl Debug for $type {
57 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
58 let hex_str = self.0.to_hex();
59 let truncated = &hex_str[..hex_str.len().min(100)];
60 let ellipsis = if hex_str.len() > 100 { "..." } else { "" };
61 write!(f, concat!(stringify!($type), "({}{})"), truncated,ellipsis)
62 }
63 }
64
65 impl Display for $type {
66 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
67 write!(f, "{}", self.0.to_hex())
68 }
69 }
70 };
71}
72
73impl Bytes {
74 pub fn is_empty(&self) -> bool {
76 self.0.is_empty()
77 }
78
79 pub fn to_short_hex(&self) -> alloc::string::String {
81 let word = sp_core::U256::from_big_endian(&self.0);
82 alloc::format!("0x{:x}", word)
83 }
84
85 pub fn to_hex_no_prefix(&self) -> alloc::string::String {
87 alloy_core::hex::encode(&self.0)
88 }
89}
90
91impl_hex!(Byte, u8, 0u8);
92impl_hex!(Bytes, Vec<u8>, vec![]);
93impl_hex!(Bytes8, [u8; 8], [0u8; 8]);
94impl_hex!(Bytes32, [u8; 32], [0u8; 32]);
95impl_hex!(Bytes256, [u8; 256], [0u8; 256]);
96
97#[test]
98fn test_to_short_hex() {
99 let bytes = Bytes(crate::U256::from(4).to_big_endian().to_vec());
100 assert_eq!(bytes.to_short_hex(), "0x4");
101}
102
103#[test]
104fn test_to_hex_no_prefix() {
105 let bytes = Bytes(vec![0x12, 0x34, 0x56, 0x78]);
106 assert_eq!(bytes.to_hex_no_prefix(), "12345678");
107}
108
109#[test]
110fn serialize_works() {
111 let a = Byte(42);
112 let s = serde_json::to_string(&a).unwrap();
113 assert_eq!(s, "\"0x2a\"");
114 let b = serde_json::from_str::<Byte>(&s).unwrap();
115 assert_eq!(a, b);
116
117 let a = Bytes(b"bello world".to_vec());
118 let s = serde_json::to_string(&a).unwrap();
119 assert_eq!(s, "\"0x62656c6c6f20776f726c64\"");
120 let b = serde_json::from_str::<Bytes>(&s).unwrap();
121 assert_eq!(a, b);
122
123 let a = Bytes256([42u8; 256]);
124 let s = serde_json::to_string(&a).unwrap();
125 let b = serde_json::from_str::<Bytes256>(&s).unwrap();
126 assert_eq!(a, b);
127}