testnumbat_wasm/types/general/
h256.rs1use crate::{abi::TypeAbi, types::BoxedBytes};
2use alloc::{boxed::Box, string::String, vec::Vec};
3use core::fmt::Debug;
4
5const ERR_BAD_H256_LENGTH: &[u8] = b"bad H256 length";
6const ZERO_32: &[u8] = &[0u8; 32];
7
8#[derive(Hash, Eq, PartialEq, Clone, Debug)]
11pub struct H256(Box<[u8; 32]>);
12
13impl From<[u8; 32]> for H256 {
14 #[inline]
20 fn from(arr: [u8; 32]) -> Self {
21 H256(Box::new(arr))
22 }
23}
24
25impl<'a> From<&'a [u8; 32]> for H256 {
26 #[inline]
33 fn from(bytes: &'a [u8; 32]) -> Self {
34 H256(Box::new(*bytes))
35 }
36}
37
38impl<'a> From<&'a mut [u8; 32]> for H256 {
39 #[inline]
46 fn from(bytes: &'a mut [u8; 32]) -> Self {
47 H256(Box::new(*bytes))
48 }
49}
50
51impl From<Box<[u8; 32]>> for H256 {
52 #[inline]
53 fn from(bytes: Box<[u8; 32]>) -> Self {
54 H256(bytes)
55 }
56}
57
58impl H256 {
59 pub fn from_slice(slice: &[u8]) -> Self {
60 let mut arr = [0u8; 32];
61 let len = core::cmp::min(slice.len(), 32);
62 arr[..len].copy_from_slice(&slice[..len]);
63 H256(Box::new(arr))
64 }
65}
66
67impl From<H256> for [u8; 32] {
68 #[inline]
69 fn from(s: H256) -> Self {
70 *(s.0)
71 }
72}
73
74impl AsRef<[u8]> for H256 {
75 #[inline]
76 fn as_ref(&self) -> &[u8] {
77 self.as_bytes()
78 }
79}
80
81impl AsMut<[u8]> for H256 {
82 #[inline]
83 fn as_mut(&mut self) -> &mut [u8] {
84 self.0.as_mut()
85 }
86}
87
88impl H256 {
89 pub fn zero() -> Self {
93 use alloc::alloc::{alloc_zeroed, Layout};
94 unsafe {
95 let ptr = alloc_zeroed(Layout::new::<[u8; 32]>()) as *mut [u8; 32];
96 H256(Box::from_raw(ptr))
97 }
98 }
99
100 #[inline]
102 pub fn len_bytes() -> usize {
103 32
104 }
105
106 #[inline]
108 pub fn as_bytes(&self) -> &[u8] {
109 self.0.as_ref()
110 }
111
112 #[inline]
113 pub fn as_array(&self) -> &[u8; 32] {
114 self.0.as_ref()
115 }
116
117 #[inline]
118 pub fn copy_to_array(&self, target: &mut [u8; 32]) {
119 target.copy_from_slice(&self.0[..]);
120 }
121
122 #[inline]
123 pub fn to_vec(&self) -> Vec<u8> {
124 self.0[..].to_vec()
125 }
126
127 #[inline]
129 pub fn as_ptr(&self) -> *const u8 {
130 self.0.as_ptr()
131 }
132
133 #[inline]
136 pub fn as_mut_ptr(&mut self) -> *mut u8 {
137 self.0.as_mut_ptr()
138 }
139
140 pub fn is_zero(&self) -> bool {
142 self.as_bytes() == ZERO_32
143 }
144
145 pub fn into_boxed_bytes(self) -> BoxedBytes {
149 let raw = Box::into_raw(self.0) as *mut u8;
150 unsafe {
151 let bytes_box = Box::<[u8]>::from_raw(core::slice::from_raw_parts_mut(raw, 32));
152 bytes_box.into()
153 }
154 }
155}
156
157use testnumbat_codec::*;
158
159impl NestedEncode for H256 {
160 fn dep_encode<O: NestedEncodeOutput>(&self, dest: &mut O) -> Result<(), EncodeError> {
161 dest.write(&self.0[..]);
162 Ok(())
163 }
164
165 fn dep_encode_or_exit<O: NestedEncodeOutput, ExitCtx: Clone>(
166 &self,
167 dest: &mut O,
168 _: ExitCtx,
169 _: fn(ExitCtx, EncodeError) -> !,
170 ) {
171 dest.write(&self.0[..]);
172 }
173}
174
175impl TopEncode for H256 {
176 fn top_encode<O: TopEncodeOutput>(&self, output: O) -> Result<(), EncodeError> {
177 output.set_slice_u8(&self.0[..]);
178 Ok(())
179 }
180
181 fn top_encode_or_exit<O: TopEncodeOutput, ExitCtx: Clone>(
182 &self,
183 output: O,
184 _: ExitCtx,
185 _: fn(ExitCtx, EncodeError) -> !,
186 ) {
187 output.set_slice_u8(&self.0[..]);
188 }
189}
190
191impl NestedDecode for H256 {
192 fn dep_decode<I: NestedDecodeInput>(input: &mut I) -> Result<Self, DecodeError> {
193 let mut res = H256::zero();
194 input.read_into(res.as_mut())?;
195 Ok(res)
196 }
197
198 fn dep_decode_or_exit<I: NestedDecodeInput, ExitCtx: Clone>(
199 input: &mut I,
200 c: ExitCtx,
201 exit: fn(ExitCtx, DecodeError) -> !,
202 ) -> Self {
203 let mut res = H256::zero();
204 input.read_into_or_exit(res.as_mut(), c, exit);
205 res
206 }
207}
208
209impl H256 {
210 pub fn decode_from_boxed_bytes_or_exit<ExitCtx: Clone>(
214 input: Box<[u8]>,
215 c: ExitCtx,
216 exit: fn(ExitCtx, DecodeError) -> !,
217 ) -> Self {
218 if input.len() != 32 {
219 exit(c, DecodeError::from(ERR_BAD_H256_LENGTH));
220 }
221 let raw = Box::into_raw(input);
222 let array_box = unsafe { Box::<[u8; 32]>::from_raw(raw as *mut [u8; 32]) };
223 H256(array_box)
224 }
225}
226
227impl TopDecode for H256 {
228 fn top_decode<I: TopDecodeInput>(input: I) -> Result<Self, DecodeError> {
229 match <[u8; 32]>::top_decode_boxed(input) {
230 Ok(array_box) => Ok(H256(array_box)),
231 Err(_) => Err(DecodeError::from(ERR_BAD_H256_LENGTH)),
232 }
233 }
234
235 fn top_decode_or_exit<I: TopDecodeInput, ExitCtx: Clone>(
236 input: I,
237 c: ExitCtx,
238 exit: fn(ExitCtx, DecodeError) -> !,
239 ) -> Self {
240 H256::decode_from_boxed_bytes_or_exit(input.into_boxed_slice_u8(), c, exit)
241 }
242}
243
244impl TypeAbi for H256 {
245 fn type_name() -> String {
246 "H256".into()
247 }
248}
249
250#[cfg(test)]
251mod h256_tests {
252 use super::*;
253 use alloc::vec::Vec;
254 use testnumbat_codec::test_util::{check_top_encode, check_top_encode_decode};
255
256 #[test]
257 fn test_h256_from_array() {
258 let addr = H256::from([4u8; 32]);
259 check_top_encode_decode(addr, &[4u8; 32]);
260 }
261
262 #[test]
263 fn test_opt_h256() {
264 let addr = H256::from([4u8; 32]);
265 let mut expected: Vec<u8> = Vec::new();
266 expected.push(1u8);
267 expected.extend_from_slice(&[4u8; 32]);
268 check_top_encode_decode(Some(addr), expected.as_slice());
269 }
270
271 #[test]
272 fn test_ser_h256_ref() {
273 let addr = H256::from([4u8; 32]);
274 let expected_bytes: &[u8] = &[4u8; 32 * 3];
275
276 let tuple = (&addr, &&&addr, addr.clone());
277 let serialized_bytes = check_top_encode(&tuple);
278 assert_eq!(serialized_bytes.as_slice(), expected_bytes);
279 }
280
281 #[test]
282 fn test_is_zero() {
283 assert!(H256::zero().is_zero());
284 }
285
286 #[test]
287 fn test_size_of() {
288 use core::mem::size_of;
289 assert_eq!(size_of::<H256>(), size_of::<usize>());
290 assert_eq!(size_of::<Option<H256>>(), size_of::<usize>());
291 }
292
293 #[test]
294 fn test_into_boxed_bytes() {
295 let array = b"32_bytes________________________";
296 let h256 = H256::from(array);
297 let bb = h256.into_boxed_bytes();
298 assert_eq!(bb.as_slice(), &array[..]);
299 }
300}