multiboot2_common/
bytes_ref.rs1use crate::{ALIGNMENT, Header, MemoryError};
4use core::marker::PhantomData;
5use core::mem;
6use core::ops::Deref;
7
8#[derive(Clone, Debug, PartialEq, Eq)]
16#[repr(transparent)]
17pub struct BytesRef<'a, H: Header> {
18 bytes: &'a [u8],
19 _h: PhantomData<H>,
22}
23
24impl<'a, H: Header> TryFrom<&'a [u8]> for BytesRef<'a, H> {
25 type Error = MemoryError;
26
27 fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
28 if bytes.len() < mem::size_of::<H>() {
29 return Err(MemoryError::ShorterThanHeader);
30 }
31 if bytes.as_ptr().align_offset(ALIGNMENT) != 0 {
33 return Err(MemoryError::WrongAlignment);
34 }
35 let padding_bytes = bytes.len() % ALIGNMENT;
36 if padding_bytes != 0 {
37 return Err(MemoryError::MissingPadding);
38 }
39 Ok(Self {
40 bytes,
41 _h: PhantomData,
42 })
43 }
44}
45
46impl<'a, H: Header> Deref for BytesRef<'a, H> {
47 type Target = &'a [u8];
48
49 fn deref(&self) -> &Self::Target {
50 &self.bytes
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use crate::test_utils::{AlignedBytes, DummyTestHeader};
58
59 #[test]
60 fn test_bytes_ref() {
61 let empty: &[u8] = &[];
62 assert_eq!(
63 BytesRef::<'_, DummyTestHeader>::try_from(empty),
64 Err(MemoryError::ShorterThanHeader)
65 );
66
67 let slice = &[0_u8, 1, 2, 3, 4, 5, 6];
68 assert_eq!(
69 BytesRef::<'_, DummyTestHeader>::try_from(&slice[..]),
70 Err(MemoryError::ShorterThanHeader)
71 );
72
73 let slice = AlignedBytes([0_u8, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0]);
74 let unaligned_slice = &slice[3..];
76 assert_eq!(
77 BytesRef::<'_, DummyTestHeader>::try_from(unaligned_slice),
78 Err(MemoryError::WrongAlignment)
79 );
80
81 let slice = AlignedBytes([0_u8, 1, 2, 3, 4, 5, 6, 7]);
82 let slice = &slice[..];
83 assert_eq!(
84 BytesRef::try_from(slice),
85 Ok(BytesRef {
86 bytes: slice,
87 _h: PhantomData::<DummyTestHeader>
88 })
89 );
90 }
91}