traits.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //! Module for the helper trait [`StructAsBytes`].
  2. use crate::{
  3. AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
  4. EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
  5. InformationRequestHeaderTag, ModuleAlignHeaderTag, Multiboot2BasicHeader, RelocatableHeaderTag,
  6. };
  7. use alloc::vec::Vec;
  8. use core::mem::size_of;
  9. /// Trait for all tags that helps to create a byte array from the tag.
  10. /// Useful in builders to construct a byte vector that
  11. /// represents the Multiboot2 header with all its tags.
  12. pub(crate) trait StructAsBytes: Sized {
  13. /// Returns the size in bytes of the struct, as known during compile
  14. /// time. This doesn't use read the "size" field of tags.
  15. fn byte_size(&self) -> usize {
  16. size_of::<Self>()
  17. }
  18. /// Returns a byte pointer to the begin of the struct.
  19. fn as_ptr(&self) -> *const u8 {
  20. self as *const Self as *const u8
  21. }
  22. /// Returns the structure as a vector of its bytes.
  23. /// The length is determined by [`Self::byte_size`].
  24. fn struct_as_bytes(&self) -> Vec<u8> {
  25. let ptr = self.as_ptr();
  26. let bytes = unsafe { core::slice::from_raw_parts(ptr, self.byte_size()) };
  27. Vec::from(bytes)
  28. }
  29. }
  30. impl StructAsBytes for AddressHeaderTag {}
  31. impl StructAsBytes for ConsoleHeaderTag {}
  32. impl StructAsBytes for EndHeaderTag {}
  33. impl StructAsBytes for EntryEfi32HeaderTag {}
  34. impl StructAsBytes for EntryEfi64HeaderTag {}
  35. impl StructAsBytes for EntryAddressHeaderTag {}
  36. impl StructAsBytes for FramebufferHeaderTag {}
  37. impl StructAsBytes for InformationRequestHeaderTag<0> {}
  38. impl StructAsBytes for ModuleAlignHeaderTag {}
  39. impl StructAsBytes for RelocatableHeaderTag {}
  40. impl StructAsBytes for EfiBootServiceHeaderTag {}
  41. impl StructAsBytes for Multiboot2BasicHeader {}
  42. #[cfg(test)]
  43. mod tests {
  44. use super::*;
  45. #[test]
  46. fn test_as_bytes() {
  47. struct Foobar {
  48. a: u32,
  49. b: u8,
  50. c: u128,
  51. }
  52. impl StructAsBytes for Foobar {}
  53. #[allow(clippy::disallowed_names)]
  54. let foo = Foobar {
  55. a: 11,
  56. b: 22,
  57. c: 33,
  58. };
  59. let bytes = foo.struct_as_bytes();
  60. let foo_from_bytes = unsafe { (bytes.as_ptr() as *const Foobar).as_ref().unwrap() };
  61. assert_eq!(bytes.len(), size_of::<Foobar>());
  62. assert_eq!(foo.a, foo_from_bytes.a);
  63. assert_eq!(foo.b, foo_from_bytes.b);
  64. assert_eq!(foo.c, foo_from_bytes.c);
  65. }
  66. }