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