multiboot2_header/
information_request.rs1use crate::{HeaderTagFlag, HeaderTagHeader};
2use crate::{HeaderTagType, MbiTagTypeId};
3use core::fmt;
4use core::fmt::{Debug, Formatter};
5use core::mem;
6#[cfg(feature = "builder")]
7use multiboot2_common::new_boxed;
8use multiboot2_common::{MaybeDynSized, Tag};
9#[cfg(feature = "builder")]
10use {
11 alloc::boxed::Box,
12 core::{ptr, slice},
13};
14
15#[derive(PartialEq, Eq, PartialOrd, Ord, Hash, ptr_meta::Pointee)]
18#[repr(C, align(8))]
19pub struct InformationRequestHeaderTag {
20 header: HeaderTagHeader,
21 requests: [MbiTagTypeId],
22}
23
24impl InformationRequestHeaderTag {
25 #[cfg(feature = "builder")]
27 #[must_use]
28 pub fn new(flags: HeaderTagFlag, requests: &[MbiTagTypeId]) -> Box<Self> {
29 let header = HeaderTagHeader::new(HeaderTagType::InformationRequest, flags, 0);
30 let requests = unsafe {
31 let ptr = ptr::addr_of!(*requests);
32 slice::from_raw_parts(ptr.cast::<u8>(), mem::size_of_val(requests))
33 };
34 new_boxed(header, &[requests])
35 }
36
37 #[must_use]
39 pub const fn typ(&self) -> HeaderTagType {
40 self.header.typ()
41 }
42
43 #[must_use]
45 pub const fn flags(&self) -> HeaderTagFlag {
46 self.header.flags()
47 }
48
49 #[must_use]
51 pub const fn size(&self) -> u32 {
52 self.header.size()
53 }
54
55 #[must_use]
57 pub const fn requests(&self) -> &[MbiTagTypeId] {
58 &self.requests
59 }
60}
61
62impl Debug for InformationRequestHeaderTag {
63 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
64 f.debug_struct("InformationRequestHeaderTag")
65 .field("type", &self.typ())
66 .field("flags", &self.flags())
67 .field("size", &self.size())
68 .field("requests", &self.requests())
69 .finish()
70 }
71}
72
73impl MaybeDynSized for InformationRequestHeaderTag {
74 type Header = HeaderTagHeader;
75
76 const BASE_SIZE: usize = mem::size_of::<HeaderTagHeader>();
77
78 fn dst_len(header: &Self::Header) -> Self::Metadata {
79 let dst_size = header.size() as usize - Self::BASE_SIZE;
80 assert_eq!(dst_size % mem::size_of::<MbiTagTypeId>(), 0);
81 dst_size / mem::size_of::<MbiTagTypeId>()
82 }
83}
84
85impl Tag for InformationRequestHeaderTag {
86 type IDType = HeaderTagType;
87 const ID: HeaderTagType = HeaderTagType::InformationRequest;
88}
89
90#[cfg(test)]
91#[cfg(feature = "builder")]
92mod tests {
93 use super::*;
94 use crate::MbiTagType;
95
96 #[test]
97 fn creation() {
98 let _ir = InformationRequestHeaderTag::new(
100 HeaderTagFlag::Optional,
101 &[
102 MbiTagType::Cmdline.into(),
103 MbiTagType::BootLoaderName.into(),
104 MbiTagType::Module.into(),
105 MbiTagType::BasicMeminfo.into(),
106 MbiTagType::Bootdev.into(),
107 MbiTagType::Mmap.into(),
108 MbiTagType::Vbe.into(),
109 MbiTagType::Framebuffer.into(),
110 MbiTagType::ElfSections.into(),
111 MbiTagType::Apm.into(),
112 MbiTagType::Efi32.into(),
113 MbiTagType::Efi64.into(),
114 MbiTagType::Smbios.into(),
115 MbiTagType::AcpiV1.into(),
116 MbiTagType::AcpiV2.into(),
117 MbiTagType::Network.into(),
118 MbiTagType::EfiMmap.into(),
119 MbiTagType::EfiBs.into(),
120 MbiTagType::Efi32Ih.into(),
121 MbiTagType::Efi64Ih.into(),
122 MbiTagType::LoadBaseAddr.into(),
123 MbiTagType::Custom(0x1337).into(),
124 ],
125 );
126 }
127}