multiversx_sc/hex_call_data/
cd_ser.rs1use crate::{
2 api::ManagedTypeApi,
3 formatter::hex_util::byte_to_hex_digits,
4 types::{ManagedArgBuffer, ManagedBuffer, heap::ArgBuffer},
5};
6use alloc::vec::Vec;
7
8use super::SEPARATOR;
9
10pub struct HexCallDataSerializer(Vec<u8>);
22
23impl HexCallDataSerializer {
24 pub fn new(endpoint_name: &[u8]) -> Self {
25 let mut data = Vec::with_capacity(endpoint_name.len());
26 data.extend_from_slice(endpoint_name);
27 HexCallDataSerializer(data)
28 }
29
30 pub fn from_arg_buffer(endpoint_name: &[u8], arg_buffer: &ArgBuffer) -> Self {
31 let mut hex_data = HexCallDataSerializer::new(endpoint_name);
32 arg_buffer.for_each_arg(|arg_bytes| hex_data.push_argument_bytes(arg_bytes));
33 hex_data
34 }
35
36 pub fn from_managed_arg_buffer<M: ManagedTypeApi>(
37 endpoint_name: &ManagedBuffer<M>,
38 arg_buffer: &ManagedArgBuffer<M>,
39 ) -> Self {
40 let mut hex_data = HexCallDataSerializer::new(endpoint_name.to_boxed_bytes().as_slice());
41 for arg in arg_buffer.raw_arg_iter() {
42 hex_data.push_argument_bytes(arg.to_boxed_bytes().as_slice());
43 }
44 hex_data
45 }
46
47 pub fn as_slice(&self) -> &[u8] {
48 self.0.as_slice()
49 }
50
51 pub fn into_vec(self) -> Vec<u8> {
52 self.0
53 }
54
55 fn push_byte(&mut self, byte: u8) {
56 let digits = byte_to_hex_digits(byte);
57 self.0.push(digits[0]);
58 self.0.push(digits[1]);
59 }
60
61 pub fn push_argument_bytes(&mut self, bytes: &[u8]) {
62 self.0.reserve(1 + bytes.len() * 2);
63 self.0.push(SEPARATOR);
64 for byte in bytes.iter() {
65 self.push_byte(*byte);
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_push_bytes_1() {
76 let mut cd = HexCallDataSerializer::new(b"func");
77 let arg_bytes: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
78 cd.push_argument_bytes(arg_bytes);
79 assert_eq!(cd.as_slice(), &b"func@0123456789abcdef"[..]);
80 }
81
82 #[test]
83 fn test_push_bytes_2() {
84 let mut cd = HexCallDataSerializer::new(b"func");
85 let arg_bytes: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
86 cd.push_argument_bytes(arg_bytes);
87 cd.push_argument_bytes(arg_bytes);
88 assert_eq!(
89 cd.as_slice(),
90 &b"func@0123456789abcdef@0123456789abcdef"[..]
91 );
92 }
93
94 #[test]
95 fn test_push_empty_1() {
96 let mut cd = HexCallDataSerializer::new(b"func");
97 cd.push_argument_bytes(&[][..]);
98 assert_eq!(cd.as_slice(), &b"func@"[..]);
99 }
100
101 #[test]
102 fn test_push_empty_2() {
103 let mut cd = HexCallDataSerializer::new(b"func");
104 cd.push_argument_bytes(&[][..]);
105 cd.push_argument_bytes(&[][..]);
106 assert_eq!(cd.as_slice(), &b"func@@"[..]);
107 }
108
109 #[test]
110 fn test_push_empty_3() {
111 let mut cd = HexCallDataSerializer::new(b"");
112 cd.push_argument_bytes(&[][..]);
113 cd.push_argument_bytes(&[][..]);
114 cd.push_argument_bytes(&[][..]);
115 assert_eq!(cd.as_slice(), &b"@@@"[..]);
116 }
117
118 #[test]
119 fn test_push_some_empty_1() {
120 let mut cd = HexCallDataSerializer::new(b"func");
121 let arg_bytes: &[u8] = &[0xff, 0xff];
122 cd.push_argument_bytes(arg_bytes);
123 cd.push_argument_bytes(&[][..]);
124 assert_eq!(cd.as_slice(), &b"func@ffff@"[..]);
125 }
126
127 #[test]
128 fn test_push_some_empty_2() {
129 let mut cd = HexCallDataSerializer::new(b"func");
130 let arg_bytes: &[u8] = &[0xff, 0xff];
131 cd.push_argument_bytes(&[][..]);
132 cd.push_argument_bytes(&[][..]);
133 cd.push_argument_bytes(arg_bytes);
134 cd.push_argument_bytes(&[][..]);
135 cd.push_argument_bytes(&[][..]);
136 assert_eq!(cd.as_slice(), &b"func@@@ffff@@"[..]);
137 }
138}