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 {
32 return Err(MemoryError::WrongAlignment);
33 }
34 let padding_bytes = bytes.len() % ALIGNMENT;
35 if padding_bytes != 0 {
36 return Err(MemoryError::MissingPadding);
37 }
38 Ok(Self {
39 bytes,
40 _h: PhantomData,
41 })
42 }
43}
44
45impl<'a, H: Header> Deref for BytesRef<'a, H> {
46 type Target = &'a [u8];
47
48 fn deref(&self) -> &Self::Target {
49 &self.bytes
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56 use crate::test_utils::{AlignedBytes, DummyTestHeader};
57
58 #[test]
59 fn test_bytes_ref() {
60 let empty: &[u8] = &[];
61 assert_eq!(
62 BytesRef::<'_, DummyTestHeader>::try_from(empty),
63 Err(MemoryError::ShorterThanHeader)
64 );
65
66 let slice = &[0_u8, 1, 2, 3, 4, 5, 6];
67 assert_eq!(
68 BytesRef::<'_, DummyTestHeader>::try_from(&slice[..]),
69 Err(MemoryError::ShorterThanHeader)
70 );
71
72 let slice = AlignedBytes([0_u8, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0]);
73 let unaligned_slice = &slice[3..];
75 assert_eq!(
76 BytesRef::<'_, DummyTestHeader>::try_from(unaligned_slice),
77 Err(MemoryError::WrongAlignment)
78 );
79
80 let slice = AlignedBytes([0_u8, 1, 2, 3, 4, 5, 6, 7]);
81 let slice = &slice[..];
82 assert_eq!(
83 BytesRef::try_from(slice),
84 Ok(BytesRef {
85 bytes: slice,
86 _h: PhantomData::<DummyTestHeader>
87 })
88 );
89 }
90}