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