Browse Source

multiboot2-header: improve code style

Philipp Schuster 10 months ago
parent
commit
b2966736b7

+ 2 - 1
multiboot2-header/Changelog.md

@@ -2,8 +2,9 @@
 
 
 ## Unreleased
 ## Unreleased
 
 
+- **Breaking** All functions that returns something useful are now `#[must_use]`
 - updated dependencies
 - updated dependencies
-- MSRV is 1.75
+- documentation enhancements
 
 
 ## 0.4.0 (2024-05-01)
 ## 0.4.0 (2024-05-01)
 
 

+ 30 - 11
multiboot2-header/src/address.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// This information does not need to be provided if the kernel image is in ELF
 /// This information does not need to be provided if the kernel image is in ELF
@@ -8,9 +8,7 @@ use core::mem::size_of;
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct AddressHeaderTag {
 pub struct AddressHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     /// Contains the address corresponding to the beginning of the Multiboot2 header — the physical memory location at which the magic value is supposed to be loaded. This field serves to synchronize the mapping between OS image offsets and physical memory addresses.
     /// Contains the address corresponding to the beginning of the Multiboot2 header — the physical memory location at which the magic value is supposed to be loaded. This field serves to synchronize the mapping between OS image offsets and physical memory addresses.
     header_addr: u32,
     header_addr: u32,
     /// Contains the physical address of the beginning of the text segment. The offset in the OS image file at which to start loading is defined by the offset at which the header was found, minus (header_addr - load_addr). load_addr must be less than or equal to header_addr.
     /// Contains the physical address of the beginning of the text segment. The offset in the OS image file at which to start loading is defined by the offset at which the header was found, minus (header_addr - load_addr). load_addr must be less than or equal to header_addr.
@@ -24,6 +22,8 @@ pub struct AddressHeaderTag {
 }
 }
 
 
 impl AddressHeaderTag {
 impl AddressHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(
     pub const fn new(
         flags: HeaderTagFlag,
         flags: HeaderTagFlag,
         header_addr: u32,
         header_addr: u32,
@@ -31,10 +31,9 @@ impl AddressHeaderTag {
         load_end_addr: u32,
         load_end_addr: u32,
         bss_end_addr: u32,
         bss_end_addr: u32,
     ) -> Self {
     ) -> Self {
-        AddressHeaderTag {
-            typ: HeaderTagType::Address,
-            flags,
-            size: size_of::<Self>() as u32,
+        let header = HeaderTagHeader::new(HeaderTagType::Address, flags, size_of::<Self>() as u32);
+        Self {
+            header,
             header_addr,
             header_addr,
             load_addr,
             load_addr,
             load_end_addr,
             load_end_addr,
@@ -42,24 +41,44 @@ impl AddressHeaderTag {
         }
         }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Returns the header address.
+    #[must_use]
     pub const fn header_addr(&self) -> u32 {
     pub const fn header_addr(&self) -> u32 {
         self.header_addr
         self.header_addr
     }
     }
+
+    /// Returns the load begin address.
+    #[must_use]
     pub const fn load_addr(&self) -> u32 {
     pub const fn load_addr(&self) -> u32 {
         self.load_addr
         self.load_addr
     }
     }
+
+    /// Returns the load end address.
+    #[must_use]
     pub const fn load_end_addr(&self) -> u32 {
     pub const fn load_end_addr(&self) -> u32 {
         self.load_end_addr
         self.load_end_addr
     }
     }
+
+    /// Returns the bss end address.
+    #[must_use]
     pub const fn bss_end_addr(&self) -> u32 {
     pub const fn bss_end_addr(&self) -> u32 {
         self.bss_end_addr
         self.bss_end_addr
     }
     }

+ 37 - 3
multiboot2-header/src/builder/header.rs

@@ -72,6 +72,8 @@ pub struct HeaderBuilder {
 }
 }
 
 
 impl HeaderBuilder {
 impl HeaderBuilder {
+    /// Creates a new builder.
+    #[must_use]
     pub const fn new(arch: HeaderTagISA) -> Self {
     pub const fn new(arch: HeaderTagISA) -> Self {
         Self {
         Self {
             arch,
             arch,
@@ -98,6 +100,7 @@ impl HeaderBuilder {
 
 
     /// Returns the expected length of the Multiboot2 header, when the
     /// Returns the expected length of the Multiboot2 header, when the
     /// [`Self::build`]-method gets called.
     /// [`Self::build`]-method gets called.
+    #[must_use]
     pub fn expected_len(&self) -> usize {
     pub fn expected_len(&self) -> usize {
         let base_len = size_of::<Multiboot2BasicHeader>();
         let base_len = size_of::<Multiboot2BasicHeader>();
         // size_or_up_aligned not required, because basic header length is 16 and the
         // size_or_up_aligned not required, because basic header length is 16 and the
@@ -159,7 +162,8 @@ impl HeaderBuilder {
     }
     }
 
 
     /// Constructs the bytes for a valid Multiboot2 header with the given properties.
     /// Constructs the bytes for a valid Multiboot2 header with the given properties.
-    pub fn build(mut self) -> HeaderBytes {
+    #[must_use]
+    pub fn build(self) -> HeaderBytes {
         const ALIGN: usize = 8;
         const ALIGN: usize = 8;
 
 
         // PHASE 1/2: Prepare Vector
         // PHASE 1/2: Prepare Vector
@@ -205,7 +209,7 @@ impl HeaderBuilder {
     }
     }
 
 
     /// Helper method that adds all the tags to the given vector.
     /// Helper method that adds all the tags to the given vector.
-    fn build_add_tags(&mut self, bytes: &mut Vec<u8>) {
+    fn build_add_tags(&self, bytes: &mut Vec<u8>) {
         Self::build_add_bytes(
         Self::build_add_bytes(
             bytes,
             bytes,
             // important that we write the correct expected length into the header!
             // important that we write the correct expected length into the header!
@@ -247,7 +251,10 @@ impl HeaderBuilder {
     }
     }
 
 
     // clippy thinks this can be a const fn but the compiler denies it
     // clippy thinks this can be a const fn but the compiler denies it
-    #[allow(clippy::missing_const_for_fn)]
+    // #[allow(clippy::missing_const_for_fn)]
+    /// Adds information requests from the
+    /// [`InformationRequestHeaderTagBuilder`] to the builder.
+    #[must_use]
     pub fn information_request_tag(
     pub fn information_request_tag(
         mut self,
         mut self,
         information_request_tag: InformationRequestHeaderTagBuilder,
         information_request_tag: InformationRequestHeaderTagBuilder,
@@ -255,38 +262,65 @@ impl HeaderBuilder {
         self.information_request_tag = Some(information_request_tag);
         self.information_request_tag = Some(information_request_tag);
         self
         self
     }
     }
+
+    /// Adds a [`AddressHeaderTag`] to the builder.
+    #[must_use]
     pub const fn address_tag(mut self, address_tag: AddressHeaderTag) -> Self {
     pub const fn address_tag(mut self, address_tag: AddressHeaderTag) -> Self {
         self.address_tag = Some(address_tag);
         self.address_tag = Some(address_tag);
         self
         self
     }
     }
+
+    /// Adds a [`EntryAddressHeaderTag`] to the builder.
+    #[must_use]
     pub const fn entry_tag(mut self, entry_tag: EntryAddressHeaderTag) -> Self {
     pub const fn entry_tag(mut self, entry_tag: EntryAddressHeaderTag) -> Self {
         self.entry_tag = Some(entry_tag);
         self.entry_tag = Some(entry_tag);
         self
         self
     }
     }
+
+    /// Adds a [`ConsoleHeaderTag`] to the builder.
+    #[must_use]
     pub const fn console_tag(mut self, console_tag: ConsoleHeaderTag) -> Self {
     pub const fn console_tag(mut self, console_tag: ConsoleHeaderTag) -> Self {
         self.console_tag = Some(console_tag);
         self.console_tag = Some(console_tag);
         self
         self
     }
     }
+
+    /// Adds a [`FramebufferHeaderTag`] to the builder.
+    #[must_use]
     pub const fn framebuffer_tag(mut self, framebuffer_tag: FramebufferHeaderTag) -> Self {
     pub const fn framebuffer_tag(mut self, framebuffer_tag: FramebufferHeaderTag) -> Self {
         self.framebuffer_tag = Some(framebuffer_tag);
         self.framebuffer_tag = Some(framebuffer_tag);
         self
         self
     }
     }
+
+    /// Adds a [`ModuleAlignHeaderTag`] to the builder.
+    #[must_use]
     pub const fn module_align_tag(mut self, module_align_tag: ModuleAlignHeaderTag) -> Self {
     pub const fn module_align_tag(mut self, module_align_tag: ModuleAlignHeaderTag) -> Self {
         self.module_align_tag = Some(module_align_tag);
         self.module_align_tag = Some(module_align_tag);
         self
         self
     }
     }
+
+    /// Adds a [`EfiBootServiceHeaderTag`] to the builder.
+    #[must_use]
     pub const fn efi_bs_tag(mut self, efi_bs_tag: EfiBootServiceHeaderTag) -> Self {
     pub const fn efi_bs_tag(mut self, efi_bs_tag: EfiBootServiceHeaderTag) -> Self {
         self.efi_bs_tag = Some(efi_bs_tag);
         self.efi_bs_tag = Some(efi_bs_tag);
         self
         self
     }
     }
+
+    /// Adds a [`EntryEfi32HeaderTag`] to the builder.
+    #[must_use]
     pub const fn efi_32_tag(mut self, efi_32_tag: EntryEfi32HeaderTag) -> Self {
     pub const fn efi_32_tag(mut self, efi_32_tag: EntryEfi32HeaderTag) -> Self {
         self.efi_32_tag = Some(efi_32_tag);
         self.efi_32_tag = Some(efi_32_tag);
         self
         self
     }
     }
+
+    /// Adds a [`EntryEfi64HeaderTag`] to the builder.
+    #[must_use]
     pub const fn efi_64_tag(mut self, efi_64_tag: EntryEfi64HeaderTag) -> Self {
     pub const fn efi_64_tag(mut self, efi_64_tag: EntryEfi64HeaderTag) -> Self {
         self.efi_64_tag = Some(efi_64_tag);
         self.efi_64_tag = Some(efi_64_tag);
         self
         self
     }
     }
+
+    /// Adds a [`RelocatableHeaderTag`] to the builder.
+    #[must_use]
     pub const fn relocatable_tag(mut self, relocatable_tag: RelocatableHeaderTag) -> Self {
     pub const fn relocatable_tag(mut self, relocatable_tag: RelocatableHeaderTag) -> Self {
         self.relocatable_tag = Some(relocatable_tag);
         self.relocatable_tag = Some(relocatable_tag);
         self
         self

+ 4 - 0
multiboot2-header/src/builder/information_request.rs

@@ -22,6 +22,7 @@ pub struct InformationRequestHeaderTagBuilder {
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 impl InformationRequestHeaderTagBuilder {
 impl InformationRequestHeaderTagBuilder {
     /// New builder.
     /// New builder.
+    #[must_use]
     pub const fn new(flag: HeaderTagFlag) -> Self {
     pub const fn new(flag: HeaderTagFlag) -> Self {
         Self {
         Self {
             irs: BTreeSet::new(),
             irs: BTreeSet::new(),
@@ -31,6 +32,7 @@ impl InformationRequestHeaderTagBuilder {
 
 
     /// Returns the expected length of the information request tag,
     /// Returns the expected length of the information request tag,
     /// when the `build`-method gets called.
     /// when the `build`-method gets called.
+    #[must_use]
     pub fn expected_len(&self) -> usize {
     pub fn expected_len(&self) -> usize {
         let basic_header_size = size_of::<InformationRequestHeaderTag<0>>();
         let basic_header_size = size_of::<InformationRequestHeaderTag<0>>();
         let req_tags_size = self.irs.len() * size_of::<MbiTagTypeId>();
         let req_tags_size = self.irs.len() * size_of::<MbiTagTypeId>();
@@ -38,12 +40,14 @@ impl InformationRequestHeaderTagBuilder {
     }
     }
 
 
     /// Adds an [`MbiTagType`] to the information request.
     /// Adds an [`MbiTagType`] to the information request.
+    #[must_use]
     pub fn add_ir(mut self, tag: MbiTagType) -> Self {
     pub fn add_ir(mut self, tag: MbiTagType) -> Self {
         self.irs.insert(tag);
         self.irs.insert(tag);
         self
         self
     }
     }
 
 
     /// Adds multiple [`MbiTagType`] to the information request.
     /// Adds multiple [`MbiTagType`] to the information request.
+    #[must_use]
     pub fn add_irs(mut self, tags: &[MbiTagType]) -> Self {
     pub fn add_irs(mut self, tags: &[MbiTagType]) -> Self {
         self.irs.extend(tags);
         self.irs.extend(tags);
         self
         self

+ 1 - 1
multiboot2-header/src/builder/traits.rs

@@ -11,7 +11,7 @@ use core::mem::size_of;
 /// Trait for all tags that helps to create a byte array from the tag.
 /// Trait for all tags that helps to create a byte array from the tag.
 /// Useful in builders to construct a byte vector that
 /// Useful in builders to construct a byte vector that
 /// represents the Multiboot2 header with all its tags.
 /// represents the Multiboot2 header with all its tags.
-pub(crate) trait StructAsBytes: Sized {
+pub trait StructAsBytes: Sized {
     /// Returns the size in bytes of the struct, as known during compile
     /// Returns the size in bytes of the struct, as known during compile
     /// time. This doesn't use read the "size" field of tags.
     /// time. This doesn't use read the "size" field of tags.
     fn byte_size(&self) -> usize {
     fn byte_size(&self) -> usize {

+ 22 - 11
multiboot2-header/src/console.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// Possible flags for [`ConsoleHeaderTag`].
 /// Possible flags for [`ConsoleHeaderTag`].
@@ -16,31 +16,42 @@ pub enum ConsoleHeaderTagFlags {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct ConsoleHeaderTag {
 pub struct ConsoleHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     console_flags: ConsoleHeaderTagFlags,
     console_flags: ConsoleHeaderTagFlags,
 }
 }
 
 
 impl ConsoleHeaderTag {
 impl ConsoleHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag, console_flags: ConsoleHeaderTagFlags) -> Self {
     pub const fn new(flags: HeaderTagFlag, console_flags: ConsoleHeaderTagFlags) -> Self {
-        ConsoleHeaderTag {
-            typ: HeaderTagType::ConsoleFlags,
-            flags,
-            size: size_of::<Self>() as u32,
+        let header =
+            HeaderTagHeader::new(HeaderTagType::ConsoleFlags, flags, size_of::<Self>() as u32);
+        Self {
+            header,
             console_flags,
             console_flags,
         }
         }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Returns the [`ConsoleHeaderTagFlags`].
+    #[must_use]
     pub const fn console_flags(&self) -> ConsoleHeaderTagFlags {
     pub const fn console_flags(&self) -> ConsoleHeaderTagFlags {
         self.console_flags
         self.console_flags
     }
     }

+ 21 - 14
multiboot2-header/src/end.rs

@@ -1,15 +1,11 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// Terminates a list of optional tags in a Multiboot2 header.
 /// Terminates a list of optional tags in a Multiboot2 header.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct EndHeaderTag {
 pub struct EndHeaderTag {
-    // u16 value
-    typ: HeaderTagType,
-    // u16 value
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
 }
 }
 
 
 impl Default for EndHeaderTag {
 impl Default for EndHeaderTag {
@@ -19,22 +15,33 @@ impl Default for EndHeaderTag {
 }
 }
 
 
 impl EndHeaderTag {
 impl EndHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new() -> Self {
     pub const fn new() -> Self {
-        EndHeaderTag {
-            typ: HeaderTagType::End,
-            flags: HeaderTagFlag::Required,
-            size: size_of::<Self>() as u32,
-        }
+        let header = HeaderTagHeader::new(
+            HeaderTagType::EntryAddress,
+            HeaderTagFlag::Required,
+            size_of::<Self>() as u32,
+        );
+        Self { header }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
 }
 }
 
 

+ 24 - 16
multiboot2-header/src/entry_address.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::fmt;
 use core::fmt;
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
@@ -8,31 +8,39 @@ use core::mem::size_of;
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct EntryAddressHeaderTag {
 pub struct EntryAddressHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     entry_addr: u32,
     entry_addr: u32,
 }
 }
 
 
 impl EntryAddressHeaderTag {
 impl EntryAddressHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
     pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
-        EntryAddressHeaderTag {
-            typ: HeaderTagType::EntryAddress,
-            flags,
-            size: size_of::<Self>() as u32,
-            entry_addr,
-        }
+        let header =
+            HeaderTagHeader::new(HeaderTagType::EntryAddress, flags, size_of::<Self>() as u32);
+        Self { header, entry_addr }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Returns the entry address.
+    #[must_use]
     pub const fn entry_addr(&self) -> u32 {
     pub const fn entry_addr(&self) -> u32 {
         self.entry_addr
         self.entry_addr
     }
     }
@@ -41,9 +49,9 @@ impl EntryAddressHeaderTag {
 impl Debug for EntryAddressHeaderTag {
 impl Debug for EntryAddressHeaderTag {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("EntryAddressHeaderTag")
         f.debug_struct("EntryAddressHeaderTag")
-            .field("type", &{ self.typ })
-            .field("flags", &{ self.flags })
-            .field("size", &{ self.size })
+            .field("type", &self.typ())
+            .field("flags", &self.flags())
+            .field("size", &self.size())
             .field("entry_addr", &(self.entry_addr as *const u32))
             .field("entry_addr", &(self.entry_addr as *const u32))
             .finish()
             .finish()
     }
     }

+ 26 - 15
multiboot2-header/src/entry_efi_32.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::fmt;
 use core::fmt;
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
@@ -12,31 +12,42 @@ use core::mem::size_of;
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct EntryEfi32HeaderTag {
 pub struct EntryEfi32HeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     entry_addr: u32,
     entry_addr: u32,
 }
 }
 
 
 impl EntryEfi32HeaderTag {
 impl EntryEfi32HeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
     pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
-        EntryEfi32HeaderTag {
-            typ: HeaderTagType::EntryAddressEFI32,
+        let header = HeaderTagHeader::new(
+            HeaderTagType::EntryAddressEFI32,
             flags,
             flags,
-            size: size_of::<Self>() as u32,
-            entry_addr,
-        }
+            size_of::<Self>() as u32,
+        );
+        Self { header, entry_addr }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Returns the entry address.
+    #[must_use]
     pub const fn entry_addr(&self) -> u32 {
     pub const fn entry_addr(&self) -> u32 {
         self.entry_addr
         self.entry_addr
     }
     }
@@ -45,9 +56,9 @@ impl EntryEfi32HeaderTag {
 impl Debug for EntryEfi32HeaderTag {
 impl Debug for EntryEfi32HeaderTag {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("EntryEfi32HeaderTag")
         f.debug_struct("EntryEfi32HeaderTag")
-            .field("type", &{ self.typ })
-            .field("flags", &{ self.flags })
-            .field("size", &{ self.size })
+            .field("type", &self.typ())
+            .field("flags", &self.flags())
+            .field("size", &self.size())
             .field("entry_addr", &(self.entry_addr as *const u32))
             .field("entry_addr", &(self.entry_addr as *const u32))
             .finish()
             .finish()
     }
     }

+ 26 - 15
multiboot2-header/src/entry_efi_64.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::fmt;
 use core::fmt;
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
@@ -12,31 +12,42 @@ use core::mem::size_of;
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct EntryEfi64HeaderTag {
 pub struct EntryEfi64HeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     entry_addr: u32,
     entry_addr: u32,
 }
 }
 
 
 impl EntryEfi64HeaderTag {
 impl EntryEfi64HeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
     pub const fn new(flags: HeaderTagFlag, entry_addr: u32) -> Self {
-        EntryEfi64HeaderTag {
-            typ: HeaderTagType::EntryAddressEFI64,
+        let header = HeaderTagHeader::new(
+            HeaderTagType::EntryAddressEFI64,
             flags,
             flags,
-            size: size_of::<Self>() as u32,
-            entry_addr,
-        }
+            size_of::<Self>() as u32,
+        );
+        Self { header, entry_addr }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Returns the entry address.
+    #[must_use]
     pub const fn entry_addr(&self) -> u32 {
     pub const fn entry_addr(&self) -> u32 {
         self.entry_addr
         self.entry_addr
     }
     }
@@ -45,9 +56,9 @@ impl EntryEfi64HeaderTag {
 impl Debug for EntryEfi64HeaderTag {
 impl Debug for EntryEfi64HeaderTag {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("EntryEfi64HeaderTag")
         f.debug_struct("EntryEfi64HeaderTag")
-            .field("type", &{ self.typ })
-            .field("flags", &{ self.flags })
-            .field("size", &{ self.size })
+            .field("type", &self.typ())
+            .field("flags", &self.flags())
+            .field("size", &self.size())
             .field("entry_addr", &(self.entry_addr as *const u32))
             .field("entry_addr", &(self.entry_addr as *const u32))
             .finish()
             .finish()
     }
     }

+ 33 - 13
multiboot2-header/src/framebuffer.rs

@@ -1,5 +1,5 @@
-use crate::{HeaderTagFlag, HeaderTagType};
-use core::mem::size_of;
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
+use core::mem;
 
 
 /// Specifies the preferred graphics mode. If this tag
 /// Specifies the preferred graphics mode. If this tag
 /// is present the bootloader assumes that the payload
 /// is present the bootloader assumes that the payload
@@ -8,41 +8,61 @@ use core::mem::size_of;
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct FramebufferHeaderTag {
 pub struct FramebufferHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     width: u32,
     width: u32,
     height: u32,
     height: u32,
     depth: u32,
     depth: u32,
 }
 }
 
 
 impl FramebufferHeaderTag {
 impl FramebufferHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag, width: u32, height: u32, depth: u32) -> Self {
     pub const fn new(flags: HeaderTagFlag, width: u32, height: u32, depth: u32) -> Self {
-        FramebufferHeaderTag {
-            typ: HeaderTagType::Framebuffer,
+        let header = HeaderTagHeader::new(
+            HeaderTagType::Framebuffer,
             flags,
             flags,
-            size: size_of::<Self>() as u32,
+            mem::size_of::<Self>() as u32,
+        );
+        Self {
+            header,
             width,
             width,
             height,
             height,
             depth,
             depth,
         }
         }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Returns the width.
+    #[must_use]
     pub const fn width(&self) -> u32 {
     pub const fn width(&self) -> u32 {
         self.width
         self.width
     }
     }
+
+    /// Returns the height.
+    #[must_use]
     pub const fn height(&self) -> u32 {
     pub const fn height(&self) -> u32 {
         self.height
         self.height
     }
     }
+
+    /// Returns the depth.
+    #[must_use]
     pub const fn depth(&self) -> u32 {
     pub const fn depth(&self) -> u32 {
         self.depth
         self.depth
     }
     }
@@ -50,12 +70,12 @@ impl FramebufferHeaderTag {
 
 
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
-    use crate::FramebufferHeaderTag;
+    use super::*;
 
 
     #[test]
     #[test]
     fn test_assert_size() {
     fn test_assert_size() {
         assert_eq!(
         assert_eq!(
-            core::mem::size_of::<FramebufferHeaderTag>(),
+            mem::size_of::<FramebufferHeaderTag>(),
             2 + 2 + 4 + 4 + 4 + 4
             2 + 2 + 4 + 4 + 4 + 4
         );
         );
     }
     }

+ 53 - 22
multiboot2-header/src/header.rs

@@ -1,8 +1,8 @@
 use crate::{
 use crate::{
     AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
     AddressHeaderTag, ConsoleHeaderTag, EfiBootServiceHeaderTag, EndHeaderTag,
     EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
     EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
-    HeaderTag, HeaderTagISA, HeaderTagType, InformationRequestHeaderTag, ModuleAlignHeaderTag,
-    RelocatableHeaderTag,
+    HeaderTagHeader, HeaderTagISA, HeaderTagType, InformationRequestHeaderTag,
+    ModuleAlignHeaderTag, RelocatableHeaderTag,
 };
 };
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
@@ -103,89 +103,106 @@ impl<'a> Multiboot2Header<'a> {
     }
     }
 
 
     /// Wrapper around [`Multiboot2BasicHeader::verify_checksum`].
     /// Wrapper around [`Multiboot2BasicHeader::verify_checksum`].
+    #[must_use]
     pub const fn verify_checksum(&self) -> bool {
     pub const fn verify_checksum(&self) -> bool {
         self.0.verify_checksum()
         self.0.verify_checksum()
     }
     }
     /// Wrapper around [`Multiboot2BasicHeader::header_magic`].
     /// Wrapper around [`Multiboot2BasicHeader::header_magic`].
+    #[must_use]
     pub const fn header_magic(&self) -> u32 {
     pub const fn header_magic(&self) -> u32 {
         self.0.header_magic()
         self.0.header_magic()
     }
     }
     /// Wrapper around [`Multiboot2BasicHeader::arch`].
     /// Wrapper around [`Multiboot2BasicHeader::arch`].
+    #[must_use]
     pub const fn arch(&self) -> HeaderTagISA {
     pub const fn arch(&self) -> HeaderTagISA {
         self.0.arch()
         self.0.arch()
     }
     }
     /// Wrapper around [`Multiboot2BasicHeader::length`].
     /// Wrapper around [`Multiboot2BasicHeader::length`].
+    #[must_use]
     pub const fn length(&self) -> u32 {
     pub const fn length(&self) -> u32 {
         self.0.length()
         self.0.length()
     }
     }
     /// Wrapper around [`Multiboot2BasicHeader::checksum`].
     /// Wrapper around [`Multiboot2BasicHeader::checksum`].
+    #[must_use]
     pub const fn checksum(&self) -> u32 {
     pub const fn checksum(&self) -> u32 {
         self.0.checksum()
         self.0.checksum()
     }
     }
     /// Wrapper around [`Multiboot2BasicHeader::tag_iter`].
     /// Wrapper around [`Multiboot2BasicHeader::tag_iter`].
+    #[must_use]
     pub fn iter(&self) -> Multiboot2HeaderTagIter {
     pub fn iter(&self) -> Multiboot2HeaderTagIter {
         self.0.tag_iter()
         self.0.tag_iter()
     }
     }
     /// Wrapper around [`Multiboot2BasicHeader::calc_checksum`].
     /// Wrapper around [`Multiboot2BasicHeader::calc_checksum`].
+    #[must_use]
     pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
     pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
         Multiboot2BasicHeader::calc_checksum(magic, arch, length)
         Multiboot2BasicHeader::calc_checksum(magic, arch, length)
     }
     }
 
 
     /// Search for the address header tag.
     /// Search for the address header tag.
+    #[must_use]
     pub fn address_tag(&self) -> Option<&AddressHeaderTag> {
     pub fn address_tag(&self) -> Option<&AddressHeaderTag> {
         self.get_tag(HeaderTagType::Address)
         self.get_tag(HeaderTagType::Address)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const AddressHeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const AddressHeaderTag) })
     }
     }
 
 
     /// Search for the entry address header tag.
     /// Search for the entry address header tag.
+    #[must_use]
     pub fn entry_address_tag(&self) -> Option<&EntryAddressHeaderTag> {
     pub fn entry_address_tag(&self) -> Option<&EntryAddressHeaderTag> {
         self.get_tag(HeaderTagType::EntryAddress)
         self.get_tag(HeaderTagType::EntryAddress)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EntryAddressHeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const EntryAddressHeaderTag) })
     }
     }
 
 
     /// Search for the EFI32 entry address header tag.
     /// Search for the EFI32 entry address header tag.
+    #[must_use]
     pub fn entry_address_efi32_tag(&self) -> Option<&EntryEfi32HeaderTag> {
     pub fn entry_address_efi32_tag(&self) -> Option<&EntryEfi32HeaderTag> {
         self.get_tag(HeaderTagType::EntryAddressEFI32)
         self.get_tag(HeaderTagType::EntryAddressEFI32)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EntryEfi32HeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const EntryEfi32HeaderTag) })
     }
     }
 
 
     /// Search for the EFI64 entry address header tag.
     /// Search for the EFI64 entry address header tag.
+    #[must_use]
     pub fn entry_address_efi64_tag(&self) -> Option<&EntryEfi64HeaderTag> {
     pub fn entry_address_efi64_tag(&self) -> Option<&EntryEfi64HeaderTag> {
         self.get_tag(HeaderTagType::EntryAddressEFI64)
         self.get_tag(HeaderTagType::EntryAddressEFI64)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EntryEfi64HeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const EntryEfi64HeaderTag) })
     }
     }
 
 
     /// Search for the console flags header tag.
     /// Search for the console flags header tag.
+    #[must_use]
     pub fn console_flags_tag(&self) -> Option<&ConsoleHeaderTag> {
     pub fn console_flags_tag(&self) -> Option<&ConsoleHeaderTag> {
         self.get_tag(HeaderTagType::ConsoleFlags)
         self.get_tag(HeaderTagType::ConsoleFlags)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const ConsoleHeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const ConsoleHeaderTag) })
     }
     }
 
 
     /// Search for the framebuffer header tag.
     /// Search for the framebuffer header tag.
+    #[must_use]
     pub fn framebuffer_tag(&self) -> Option<&FramebufferHeaderTag> {
     pub fn framebuffer_tag(&self) -> Option<&FramebufferHeaderTag> {
         self.get_tag(HeaderTagType::Framebuffer)
         self.get_tag(HeaderTagType::Framebuffer)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const FramebufferHeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const FramebufferHeaderTag) })
     }
     }
 
 
     /// Search for the module align header tag.
     /// Search for the module align header tag.
+    #[must_use]
     pub fn module_align_tag(&self) -> Option<&ModuleAlignHeaderTag> {
     pub fn module_align_tag(&self) -> Option<&ModuleAlignHeaderTag> {
         self.get_tag(HeaderTagType::ModuleAlign)
         self.get_tag(HeaderTagType::ModuleAlign)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const ModuleAlignHeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const ModuleAlignHeaderTag) })
     }
     }
 
 
     /// Search for the EFI Boot Services header tag.
     /// Search for the EFI Boot Services header tag.
+    #[must_use]
     pub fn efi_boot_services_tag(&self) -> Option<&EfiBootServiceHeaderTag> {
     pub fn efi_boot_services_tag(&self) -> Option<&EfiBootServiceHeaderTag> {
-        self.get_tag(HeaderTagType::EfiBS)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const EfiBootServiceHeaderTag) })
+        self.get_tag(HeaderTagType::EfiBS).map(|tag| unsafe {
+            &*(tag as *const HeaderTagHeader as *const EfiBootServiceHeaderTag)
+        })
     }
     }
 
 
     /// Search for the EFI32 entry address header tag.
     /// Search for the EFI32 entry address header tag.
+    #[must_use]
     pub fn relocatable_tag(&self) -> Option<&RelocatableHeaderTag> {
     pub fn relocatable_tag(&self) -> Option<&RelocatableHeaderTag> {
         self.get_tag(HeaderTagType::Relocatable)
         self.get_tag(HeaderTagType::Relocatable)
-            .map(|tag| unsafe { &*(tag as *const HeaderTag as *const RelocatableHeaderTag) })
+            .map(|tag| unsafe { &*(tag as *const HeaderTagHeader as *const RelocatableHeaderTag) })
     }
     }
 
 
-    fn get_tag(&self, typ: HeaderTagType) -> Option<&HeaderTag> {
+    fn get_tag(&self, typ: HeaderTagType) -> Option<&HeaderTagHeader> {
         self.iter()
         self.iter()
             .map(|tag| unsafe { tag.as_ref() }.unwrap())
             .map(|tag| unsafe { tag.as_ref() }.unwrap())
             .find(|tag| tag.typ() == typ)
             .find(|tag| tag.typ() == typ)
@@ -229,7 +246,7 @@ impl Multiboot2BasicHeader {
     pub(crate) const fn new(arch: HeaderTagISA, length: u32) -> Self {
     pub(crate) const fn new(arch: HeaderTagISA, length: u32) -> Self {
         let magic = MAGIC;
         let magic = MAGIC;
         let checksum = Self::calc_checksum(magic, arch, length);
         let checksum = Self::calc_checksum(magic, arch, length);
-        Multiboot2BasicHeader {
+        Self {
             header_magic: magic,
             header_magic: magic,
             arch,
             arch,
             length,
             length,
@@ -238,25 +255,38 @@ impl Multiboot2BasicHeader {
     }
     }
 
 
     /// Verifies that a Multiboot2 header is valid.
     /// Verifies that a Multiboot2 header is valid.
+    #[must_use]
     pub const fn verify_checksum(&self) -> bool {
     pub const fn verify_checksum(&self) -> bool {
         let check = Self::calc_checksum(self.header_magic, self.arch, self.length);
         let check = Self::calc_checksum(self.header_magic, self.arch, self.length);
         check == self.checksum
         check == self.checksum
     }
     }
 
 
     /// Calculates the checksum as described in the spec.
     /// Calculates the checksum as described in the spec.
+    #[must_use]
     pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
     pub const fn calc_checksum(magic: u32, arch: HeaderTagISA, length: u32) -> u32 {
         (0x100000000 - magic as u64 - arch as u64 - length as u64) as u32
         (0x100000000 - magic as u64 - arch as u64 - length as u64) as u32
     }
     }
 
 
+    /// Returns the header magic.
+    #[must_use]
     pub const fn header_magic(&self) -> u32 {
     pub const fn header_magic(&self) -> u32 {
         self.header_magic
         self.header_magic
     }
     }
+
+    /// Returns the [`HeaderTagISA`].
+    #[must_use]
     pub const fn arch(&self) -> HeaderTagISA {
     pub const fn arch(&self) -> HeaderTagISA {
         self.arch
         self.arch
     }
     }
+
+    /// Returns the length.
+    #[must_use]
     pub const fn length(&self) -> u32 {
     pub const fn length(&self) -> u32 {
         self.length
         self.length
     }
     }
+
+    /// Returns the checksum.
+    #[must_use]
     pub const fn checksum(&self) -> u32 {
     pub const fn checksum(&self) -> u32 {
         self.checksum
         self.checksum
     }
     }
@@ -265,12 +295,13 @@ impl Multiboot2BasicHeader {
     ///
     ///
     /// # Panics
     /// # Panics
     /// See doc of [`Multiboot2HeaderTagIter`].
     /// See doc of [`Multiboot2HeaderTagIter`].
+    #[must_use]
     pub fn tag_iter(&self) -> Multiboot2HeaderTagIter {
     pub fn tag_iter(&self) -> Multiboot2HeaderTagIter {
-        let base_hdr_size = size_of::<Multiboot2BasicHeader>();
+        let base_hdr_size = size_of::<Self>();
         if base_hdr_size == self.length as usize {
         if base_hdr_size == self.length as usize {
             panic!("No end tag!");
             panic!("No end tag!");
         }
         }
-        let tag_base_addr = self as *const Multiboot2BasicHeader;
+        let tag_base_addr = self as *const Self;
         // cast to u8 so that the offset in bytes works correctly
         // cast to u8 so that the offset in bytes works correctly
         let tag_base_addr = tag_base_addr as *const u8;
         let tag_base_addr = tag_base_addr as *const u8;
         // tag_base_addr should now point behind the "static" members
         // tag_base_addr should now point behind the "static" members
@@ -278,7 +309,7 @@ impl Multiboot2BasicHeader {
         // align pointer to 8 byte according to spec
         // align pointer to 8 byte according to spec
         let tag_base_addr = unsafe { tag_base_addr.add(tag_base_addr.align_offset(8)) };
         let tag_base_addr = unsafe { tag_base_addr.add(tag_base_addr.align_offset(8)) };
         // cast back
         // cast back
-        let tag_base_addr = tag_base_addr as *const HeaderTag;
+        let tag_base_addr = tag_base_addr as *const HeaderTagHeader;
         let tags_len = self.length as usize - base_hdr_size;
         let tags_len = self.length as usize - base_hdr_size;
         Multiboot2HeaderTagIter::new(tag_base_addr, tags_len as u32)
         Multiboot2HeaderTagIter::new(tag_base_addr, tags_len as u32)
     }
     }
@@ -307,7 +338,7 @@ impl Debug for Multiboot2BasicHeader {
 #[derive(Clone)]
 #[derive(Clone)]
 pub struct Multiboot2HeaderTagIter {
 pub struct Multiboot2HeaderTagIter {
     /// 8-byte aligned base address
     /// 8-byte aligned base address
-    base: *const HeaderTag,
+    base: *const HeaderTagHeader,
     /// Offset in bytes from the base address.
     /// Offset in bytes from the base address.
     /// Always <= than size.
     /// Always <= than size.
     n: u32,
     n: u32,
@@ -324,11 +355,11 @@ pub struct Multiboot2HeaderTagIter {
 }
 }
 
 
 impl Multiboot2HeaderTagIter {
 impl Multiboot2HeaderTagIter {
-    fn new(base: *const HeaderTag, size: u32) -> Self {
+    fn new(base: *const HeaderTagHeader, size: u32) -> Self {
         // transform to byte pointer => offset works properly
         // transform to byte pointer => offset works properly
         let base = base as *const u8;
         let base = base as *const u8;
         let base = unsafe { base.add(base.align_offset(8)) };
         let base = unsafe { base.add(base.align_offset(8)) };
-        let base = base as *const HeaderTag;
+        let base = base as *const HeaderTagHeader;
         Self {
         Self {
             base,
             base,
             n: 0,
             n: 0,
@@ -340,7 +371,7 @@ impl Multiboot2HeaderTagIter {
 }
 }
 
 
 impl Iterator for Multiboot2HeaderTagIter {
 impl Iterator for Multiboot2HeaderTagIter {
-    type Item = *const HeaderTag;
+    type Item = *const HeaderTagHeader;
 
 
     fn next(&mut self) -> Option<Self::Item> {
     fn next(&mut self) -> Option<Self::Item> {
         // no more bytes left to check; length reached
         // no more bytes left to check; length reached
@@ -351,7 +382,7 @@ impl Iterator for Multiboot2HeaderTagIter {
         // transform to byte ptr => offset works correctly
         // transform to byte ptr => offset works correctly
         let ptr = self.base as *const u8;
         let ptr = self.base as *const u8;
         let ptr = unsafe { ptr.add(self.n as usize) };
         let ptr = unsafe { ptr.add(self.n as usize) };
-        let ptr = ptr as *const HeaderTag;
+        let ptr = ptr as *const HeaderTagHeader;
         assert_eq!(ptr as usize % 8, 0, "must be 8-byte aligned");
         assert_eq!(ptr as usize % 8, 0, "must be 8-byte aligned");
         let tag = unsafe { &*ptr };
         let tag = unsafe { &*ptr };
         assert!(
         assert!(

+ 28 - 18
multiboot2-header/src/information_request.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, MbiTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, MbiTagType};
 use crate::{HeaderTagType, MbiTagTypeId};
 use crate::{HeaderTagType, MbiTagTypeId};
 use core::fmt;
 use core::fmt;
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
@@ -11,9 +11,7 @@ use multiboot2::TagType;
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct InformationRequestHeaderTag<const N: usize> {
 pub struct InformationRequestHeaderTag<const N: usize> {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     // Length is determined by size.
     // Length is determined by size.
     // Must be parsed during runtime with unsafe pointer magic and the size field.
     // Must be parsed during runtime with unsafe pointer magic and the size field.
     requests: [MbiTagTypeId; N],
     requests: [MbiTagTypeId; N],
@@ -23,28 +21,38 @@ impl<const N: usize> InformationRequestHeaderTag<N> {
     /// Creates a new object. The size parameter is the value of the size property.
     /// Creates a new object. The size parameter is the value of the size property.
     /// It doesn't have to match with `N` necessarily, because during compile time we
     /// It doesn't have to match with `N` necessarily, because during compile time we
     /// can't know the size of the tag in all runtime situations.
     /// can't know the size of the tag in all runtime situations.
+    #[must_use]
     pub fn new(flags: HeaderTagFlag, requests: [MbiTagTypeId; N], size: Option<u32>) -> Self {
     pub fn new(flags: HeaderTagFlag, requests: [MbiTagTypeId; N], size: Option<u32>) -> Self {
-        InformationRequestHeaderTag {
-            typ: HeaderTagType::InformationRequest,
+        let header = HeaderTagHeader::new(
+            HeaderTagType::InformationRequest,
             flags,
             flags,
-            size: size.unwrap_or(size_of::<Self>() as u32),
-            requests,
-        }
+            size.unwrap_or(size_of::<Self>() as u32),
+        );
+        Self { header, requests }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
 
 
     /// Returns the requests as array. Only works if the number of requests
     /// Returns the requests as array. Only works if the number of requests
     /// is known at compile time. For safety and correctness during runtime,
     /// is known at compile time. For safety and correctness during runtime,
     /// you should use `req_iter()`.
     /// you should use `req_iter()`.
+    #[must_use]
     pub const fn requests(&self) -> [MbiTagTypeId; N] {
     pub const fn requests(&self) -> [MbiTagTypeId; N] {
         // cheap to copy, otherwise difficult with lifetime
         // cheap to copy, otherwise difficult with lifetime
         self.requests
         self.requests
@@ -54,9 +62,10 @@ impl<const N: usize> InformationRequestHeaderTag<N> {
     /// from the `size`-property. This method is useful
     /// from the `size`-property. This method is useful
     /// because this struct uses a const generic, but during runtime
     /// because this struct uses a const generic, but during runtime
     /// we don't know the value in almost any case.
     /// we don't know the value in almost any case.
+    #[must_use]
     pub const fn dynamic_requests_size(&self) -> u32 {
     pub const fn dynamic_requests_size(&self) -> u32 {
         let base_struct_size = size_of::<InformationRequestHeaderTag<0>>();
         let base_struct_size = size_of::<InformationRequestHeaderTag<0>>();
-        let size_diff = self.size - base_struct_size as u32;
+        let size_diff = self.size() - base_struct_size as u32;
         if size_diff > 0 {
         if size_diff > 0 {
             size_diff / size_of::<u32>() as u32
             size_diff / size_of::<u32>() as u32
         } else {
         } else {
@@ -65,10 +74,11 @@ impl<const N: usize> InformationRequestHeaderTag<N> {
     }
     }
 
 
     /// Returns an [`InformationRequestHeaderTagIter`].
     /// Returns an [`InformationRequestHeaderTagIter`].
+    #[must_use]
     pub const fn req_iter(&self) -> InformationRequestHeaderTagIter {
     pub const fn req_iter(&self) -> InformationRequestHeaderTagIter {
         let base_struct_size = size_of::<InformationRequestHeaderTag<0>>();
         let base_struct_size = size_of::<InformationRequestHeaderTag<0>>();
         let count = self.dynamic_requests_size();
         let count = self.dynamic_requests_size();
-        let base_ptr = self as *const InformationRequestHeaderTag<N>;
+        let base_ptr = self as *const Self;
         let base_ptr = base_ptr as *const u8;
         let base_ptr = base_ptr as *const u8;
         let base_ptr = unsafe { base_ptr.add(base_struct_size) };
         let base_ptr = unsafe { base_ptr.add(base_struct_size) };
         let base_ptr = base_ptr as *const MbiTagTypeId;
         let base_ptr = base_ptr as *const MbiTagTypeId;
@@ -79,10 +89,10 @@ impl<const N: usize> InformationRequestHeaderTag<N> {
 impl<const N: usize> Debug for InformationRequestHeaderTag<N> {
 impl<const N: usize> Debug for InformationRequestHeaderTag<N> {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("InformationRequestHeaderTag")
         f.debug_struct("InformationRequestHeaderTag")
-            .field("type", &{ self.typ })
-            .field("flags", &{ self.flags })
-            .field("size", &{ self.size })
-            .field("requests", &{ self.req_iter() })
+            .field("type", &self.typ())
+            .field("flags", &self.flags())
+            .field("size", &self.size())
+            .field("requests", &self.req_iter())
             .finish()
             .finish()
     }
     }
 }
 }

+ 15 - 3
multiboot2-header/src/lib.rs

@@ -38,10 +38,22 @@
 
 
 #![no_std]
 #![no_std]
 #![cfg_attr(feature = "unstable", feature(error_in_core))]
 #![cfg_attr(feature = "unstable", feature(error_in_core))]
-#![deny(rustdoc::all)]
-#![deny(clippy::all)]
-#![deny(clippy::missing_const_for_fn)]
+// --- BEGIN STYLE CHECKS ---
+#![deny(
+    clippy::all,
+    clippy::cargo,
+    clippy::nursery,
+    clippy::must_use_candidate,
+    // clippy::restriction,
+    // clippy::pedantic
+)]
+// now allow a few rules which are denied by the above statement
+// --> They are either ridiculous, not necessary, or we can't fix them.
+#![allow(clippy::multiple_crate_versions)]
+#![deny(missing_docs)]
 #![deny(missing_debug_implementations)]
 #![deny(missing_debug_implementations)]
+#![deny(rustdoc::all)]
+// --- END STYLE CHECKS ---
 
 
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 extern crate alloc;
 extern crate alloc;

+ 18 - 12
multiboot2-header/src/module_align.rs

@@ -1,32 +1,38 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// If this tag is present, provided boot modules must be page aligned.
 /// If this tag is present, provided boot modules must be page aligned.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct ModuleAlignHeaderTag {
 pub struct ModuleAlignHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
 }
 }
 
 
 impl ModuleAlignHeaderTag {
 impl ModuleAlignHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag) -> Self {
     pub const fn new(flags: HeaderTagFlag) -> Self {
-        ModuleAlignHeaderTag {
-            typ: HeaderTagType::ModuleAlign,
-            flags,
-            size: size_of::<Self>() as u32,
-        }
+        let header =
+            HeaderTagHeader::new(HeaderTagType::ModuleAlign, flags, size_of::<Self>() as u32);
+        Self { header }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
 }
 }
 
 

+ 34 - 14
multiboot2-header/src/relocatable.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::fmt;
 use core::fmt;
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
@@ -22,9 +22,7 @@ pub enum RelocatableHeaderTagPreference {
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct RelocatableHeaderTag {
 pub struct RelocatableHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
     /// Lowest possible physical address at which image should be loaded. The bootloader cannot load any part of image below this address
     /// Lowest possible physical address at which image should be loaded. The bootloader cannot load any part of image below this address
     min_addr: u32,
     min_addr: u32,
     /// Highest possible physical address at which loaded image should end. The bootloader cannot load any part of image above this address.
     /// Highest possible physical address at which loaded image should end. The bootloader cannot load any part of image above this address.
@@ -35,6 +33,8 @@ pub struct RelocatableHeaderTag {
 }
 }
 
 
 impl RelocatableHeaderTag {
 impl RelocatableHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(
     pub const fn new(
         flags: HeaderTagFlag,
         flags: HeaderTagFlag,
         min_addr: u32,
         min_addr: u32,
@@ -42,10 +42,10 @@ impl RelocatableHeaderTag {
         align: u32,
         align: u32,
         preference: RelocatableHeaderTagPreference,
         preference: RelocatableHeaderTagPreference,
     ) -> Self {
     ) -> Self {
-        RelocatableHeaderTag {
-            typ: HeaderTagType::Relocatable,
-            flags,
-            size: size_of::<Self>() as u32,
+        let header =
+            HeaderTagHeader::new(HeaderTagType::Relocatable, flags, size_of::<Self>() as u32);
+        Self {
+            header,
             min_addr,
             min_addr,
             max_addr,
             max_addr,
             align,
             align,
@@ -53,24 +53,44 @@ impl RelocatableHeaderTag {
         }
         }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
+
+    /// Return the minimum address.
+    #[must_use]
     pub const fn min_addr(&self) -> u32 {
     pub const fn min_addr(&self) -> u32 {
         self.min_addr
         self.min_addr
     }
     }
+
+    /// Return the maximum address.
+    #[must_use]
     pub const fn max_addr(&self) -> u32 {
     pub const fn max_addr(&self) -> u32 {
         self.max_addr
         self.max_addr
     }
     }
+
+    /// Return the alignment.
+    #[must_use]
     pub const fn align(&self) -> u32 {
     pub const fn align(&self) -> u32 {
         self.align
         self.align
     }
     }
+
+    /// Return the preference.
+    #[must_use]
     pub const fn preference(&self) -> RelocatableHeaderTagPreference {
     pub const fn preference(&self) -> RelocatableHeaderTagPreference {
         self.preference
         self.preference
     }
     }
@@ -79,9 +99,9 @@ impl RelocatableHeaderTag {
 impl Debug for RelocatableHeaderTag {
 impl Debug for RelocatableHeaderTag {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         f.debug_struct("RelocatableHeaderTag")
         f.debug_struct("RelocatableHeaderTag")
-            .field("type", &{ self.typ })
-            .field("flags", &{ self.flags })
-            .field("size", &{ self.size })
+            .field("type", &self.typ())
+            .field("flags", &self.flags())
+            .field("size", &self.size())
             // trick to print this as hexadecimal pointer
             // trick to print this as hexadecimal pointer
             .field("min_addr", &(self.min_addr as *const u32))
             .field("min_addr", &(self.min_addr as *const u32))
             .field("max_addr", &(self.max_addr as *const u32))
             .field("max_addr", &(self.max_addr as *const u32))

+ 28 - 12
multiboot2-header/src/tags.rs

@@ -17,7 +17,7 @@ pub enum HeaderTagISA {
 
 
 /// Possible types for header tags of a Multiboot2 header. The names and values are taken
 /// Possible types for header tags of a Multiboot2 header. The names and values are taken
 /// from the example C code at the bottom of the Multiboot2 specification. This value
 /// from the example C code at the bottom of the Multiboot2 specification. This value
-/// stands in the `typ` property of [`crate::tags::HeaderTag`].
+/// stands in the `typ` property of [`HeaderTagHeader`].
 #[repr(u16)]
 #[repr(u16)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum HeaderTagType {
 pub enum HeaderTagType {
@@ -47,6 +47,7 @@ pub enum HeaderTagType {
 
 
 impl HeaderTagType {
 impl HeaderTagType {
     /// Returns the number of possible variants.
     /// Returns the number of possible variants.
+    #[must_use]
     pub const fn count() -> u32 {
     pub const fn count() -> u32 {
         11
         11
     }
     }
@@ -56,31 +57,46 @@ impl HeaderTagType {
 #[repr(u16)]
 #[repr(u16)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum HeaderTagFlag {
 pub enum HeaderTagFlag {
+    /// Bootloader must provide this tag. If this is not possible, the
+    /// bootloader will fail loading the kernel.
     Required = 0,
     Required = 0,
+    /// Bootloader should provide the tag if possible.
     Optional = 1,
     Optional = 1,
 }
 }
 
 
-/// Common properties for all header tags. Other tags may have additional fields
-/// that depend on the `typ` and the `size` field. All tags share the same beginning of the
-/// struct.
+/// The common header that all header tags share. Specific tags may have
+/// additional fields that depend on the `typ` and the `size` field.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
-pub struct HeaderTag {
+pub struct HeaderTagHeader {
+    typ: HeaderTagType, /* u16 */
     // u16 value
     // u16 value
-    typ: HeaderTagType,
-    // u16 value
-    flags: HeaderTagFlag,
+    flags: HeaderTagFlag, /* u16 */
     size: u32,
     size: u32,
-    // maybe additional fields (tag specific)
+    // Followed by optional additional tag specific fields.
 }
 }
 
 
-impl HeaderTag {
+impl HeaderTagHeader {
+    /// Creates a new header.
+    #[must_use]
+    pub const fn new(typ: HeaderTagType, flags: HeaderTagFlag, size: u32) -> Self {
+        Self { typ, flags, size }
+    }
+
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
         self.typ
         self.typ
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
         self.flags
         self.flags
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
         self.size
         self.size
     }
     }
@@ -88,10 +104,10 @@ impl HeaderTag {
 
 
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
-    use crate::HeaderTag;
+    use crate::HeaderTagHeader;
 
 
     #[test]
     #[test]
     fn test_assert_size() {
     fn test_assert_size() {
-        assert_eq!(core::mem::size_of::<HeaderTag>(), 2 + 2 + 4);
+        assert_eq!(core::mem::size_of::<HeaderTagHeader>(), 2 + 2 + 4);
     }
     }
 }
 }

+ 17 - 12
multiboot2-header/src/uefi_bs.rs

@@ -1,4 +1,4 @@
-use crate::{HeaderTagFlag, HeaderTagType};
+use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// This tag indicates that payload supports starting without terminating UEFI boot services.
 /// This tag indicates that payload supports starting without terminating UEFI boot services.
@@ -6,28 +6,33 @@ use core::mem::size_of;
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(C)]
 #[repr(C)]
 pub struct EfiBootServiceHeaderTag {
 pub struct EfiBootServiceHeaderTag {
-    typ: HeaderTagType,
-    flags: HeaderTagFlag,
-    size: u32,
+    header: HeaderTagHeader,
 }
 }
 
 
 impl EfiBootServiceHeaderTag {
 impl EfiBootServiceHeaderTag {
+    /// Constructs a new tag.
+    #[must_use]
     pub const fn new(flags: HeaderTagFlag) -> Self {
     pub const fn new(flags: HeaderTagFlag) -> Self {
-        EfiBootServiceHeaderTag {
-            typ: HeaderTagType::EfiBS,
-            flags,
-            size: size_of::<Self>() as u32,
-        }
+        let header = HeaderTagHeader::new(HeaderTagType::EfiBS, flags, size_of::<Self>() as u32);
+        Self { header }
     }
     }
 
 
+    /// Returns the [`HeaderTagType`].
+    #[must_use]
     pub const fn typ(&self) -> HeaderTagType {
     pub const fn typ(&self) -> HeaderTagType {
-        self.typ
+        self.header.typ()
     }
     }
+
+    /// Returns the [`HeaderTagFlag`]s.
+    #[must_use]
     pub const fn flags(&self) -> HeaderTagFlag {
     pub const fn flags(&self) -> HeaderTagFlag {
-        self.flags
+        self.header.flags()
     }
     }
+
+    /// Returns the size.
+    #[must_use]
     pub const fn size(&self) -> u32 {
     pub const fn size(&self) -> u32 {
-        self.size
+        self.header.size()
     }
     }
 }
 }