1use std::array::TryFromSliceError;
2use std::convert::TryInto;
3use std::mem;
4use zerocopy::byteorder::big_endian;
5
6pub trait TryFromByteSlice {
7 fn try_from_byte_slice(bytes: &[u8]) -> Result<&Self, TryFromSliceError>;
8}
9
10impl<const N: usize> TryFromByteSlice for [u8; N] {
11 fn try_from_byte_slice(bytes: &[u8]) -> Result<&[u8; N], TryFromSliceError> {
12 bytes.try_into()
13 }
14}
15
16pub trait ByteArray {
17 type ByteArray: AsRef<[u8]> + TryFromByteSlice;
18}
19
20pub trait AsBytesExt: ByteArray + zerocopy::AsBytes {
21 fn as_byte_array(&self) -> &Self::ByteArray {
22 TryFromByteSlice::try_from_byte_slice(self.as_bytes()).unwrap()
23 }
24}
25
26pub trait FromBytesExt: ByteArray + zerocopy::FromBytes {
27 fn ref_and_rest_from(bytes: &[u8]) -> Option<(&Self, &[u8])>
28 where
29 Self: Sized,
30 {
31 if bytes.len() < mem::size_of::<Self>() {
32 return None;
33 }
34 let (result, rest) = bytes.split_at(mem::size_of::<Self>());
35 Some((Self::ref_from(result).unwrap(), rest))
36 }
37 fn ref_from_array(bytes: &Self::ByteArray) -> &Self
38 where
39 Self: Sized,
40 {
41 Self::ref_from(bytes.as_ref()).unwrap()
42 }
43 fn from_array(bytes: Self::ByteArray) -> Self
44 where
45 Self: Copy + Sized,
46 {
47 *Self::ref_from_array(&bytes)
48 }
49}
50
51impl<T: ByteArray + zerocopy::AsBytes> AsBytesExt for T {}
52impl<T: ByteArray + zerocopy::FromBytes> FromBytesExt for T {}
53
54boilerplate_packed_internal!(big_endian::U32, 4, test_be_u32_size);