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