소스 검색

multiboot2: add Tag::cast_tag to prevent code duplication

Philipp Schuster 2 년 전
부모
커밋
bd73c24374
2개의 변경된 파일19개의 추가작업 그리고 12개의 파일을 삭제
  1. 12 12
      multiboot2/src/lib.rs
  2. 7 0
      multiboot2/src/tag_type.rs

+ 12 - 12
multiboot2/src/lib.rs

@@ -225,7 +225,7 @@ impl BootInformation {
     /// Search for the Memory map tag.
     pub fn memory_map_tag(&self) -> Option<&MemoryMapTag> {
         self.get_tag(TagType::Mmap)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const MemoryMapTag) })
+            .map(|tag| tag.cast_tag::<MemoryMapTag>())
     }
 
     /// Get an iterator of all module tags.
@@ -236,13 +236,13 @@ impl BootInformation {
     /// Search for the BootLoader name tag.
     pub fn boot_loader_name_tag(&self) -> Option<&BootLoaderNameTag> {
         self.get_tag(TagType::BootLoaderName)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const BootLoaderNameTag) })
+            .map(|tag| tag.cast_tag::<BootLoaderNameTag>())
     }
 
     /// Search for the Command line tag.
     pub fn command_line_tag(&self) -> Option<&CommandLineTag> {
         self.get_tag(TagType::Cmdline)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const CommandLineTag) })
+            .map(|tag| tag.cast_tag::<CommandLineTag>())
     }
 
     /// Search for the VBE framebuffer tag. The result is `Some(Err(e))`, if the
@@ -255,25 +255,25 @@ impl BootInformation {
     /// Search for the EFI 32-bit SDT tag.
     pub fn efi_sdt_32_tag(&self) -> Option<&EFISdt32> {
         self.get_tag(TagType::Efi32)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const EFISdt32) })
+            .map(|tag| tag.cast_tag::<EFISdt32>())
     }
 
     /// Search for the EFI 64-bit SDT tag.
     pub fn efi_sdt_64_tag(&self) -> Option<&EFISdt64> {
         self.get_tag(TagType::Efi64)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const EFISdt64) })
+            .map(|tag| tag.cast_tag::<EFISdt64>())
     }
 
     /// Search for the (ACPI 1.0) RSDP tag.
     pub fn rsdp_v1_tag(&self) -> Option<&RsdpV1Tag> {
         self.get_tag(TagType::AcpiV1)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const RsdpV1Tag) })
+            .map(|tag| tag.cast_tag::<RsdpV1Tag>())
     }
 
     /// Search for the (ACPI 2.0 or later) RSDP tag.
     pub fn rsdp_v2_tag(&self) -> Option<&RsdpV2Tag> {
         self.get_tag(TagType::AcpiV2)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const RsdpV2Tag) })
+            .map(|tag| tag.cast_tag::<RsdpV2Tag>())
     }
 
     /// Search for the EFI Memory map tag, if the boot services were exited.
@@ -287,32 +287,32 @@ impl BootInformation {
             Some(_tag) => None,
             None => self
                 .get_tag(TagType::EfiMmap)
-                .map(|tag| unsafe { &*(tag as *const Tag as *const EFIMemoryMapTag) }),
+                .map(|tag| tag.cast_tag::<EFIMemoryMapTag>()),
         }
     }
 
     /// Search for the EFI 32-bit image handle pointer.
     pub fn efi_32_ih(&self) -> Option<&EFIImageHandle32> {
         self.get_tag(TagType::Efi32Ih)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const EFIImageHandle32) })
+            .map(|tag| tag.cast_tag::<EFIImageHandle32>())
     }
 
     /// Search for the EFI 64-bit image handle pointer.
     pub fn efi_64_ih(&self) -> Option<&EFIImageHandle64> {
         self.get_tag(TagType::Efi64Ih)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const EFIImageHandle64) })
+            .map(|tag| tag.cast_tag::<EFIImageHandle64>())
     }
 
     /// Search for the Image Load Base Physical Address.
     pub fn load_base_addr(&self) -> Option<&ImageLoadPhysAddr> {
         self.get_tag(TagType::LoadBaseAddr)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const ImageLoadPhysAddr) })
+            .map(|tag| tag.cast_tag::<ImageLoadPhysAddr>())
     }
 
     /// Search for the VBE information tag.
     pub fn vbe_info_tag(&self) -> Option<&VBEInfoTag> {
         self.get_tag(TagType::Vbe)
-            .map(|tag| unsafe { &*(tag as *const Tag as *const VBEInfoTag) })
+            .map(|tag| tag.cast_tag::<VBEInfoTag>())
     }
 
     fn get(&self) -> &BootInformationInner {

+ 7 - 0
multiboot2/src/tag_type.rs

@@ -114,6 +114,13 @@ pub struct Tag {
     // tag specific fields
 }
 
+impl Tag {
+    /// Casts the base tag to the specific tag type.
+    pub fn cast_tag<'a, T>(&self) -> &'a T {
+        unsafe { &*(self as *const Tag as *const T) }
+    }
+}
+
 impl Debug for Tag {
     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
         f.debug_struct("Tag")