Skip to content

Commit cdfc1c7

Browse files
committed
multiboot2: simplify usage of cast_tag::<T>()
1 parent ff60f05 commit cdfc1c7

File tree

1 file changed

+31
-39
lines changed

1 file changed

+31
-39
lines changed

multiboot2/src/lib.rs

+31-39
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,13 @@ impl BootInformation {
218218

219219
/// Search for the ELF Sections tag.
220220
pub fn elf_sections_tag(&self) -> Option<ElfSectionsTag> {
221-
self.get_tag(TagType::ElfSections)
221+
self.get_tag::<Tag, _>(TagType::ElfSections)
222222
.map(|tag| unsafe { elf_sections::elf_sections_tag(tag, self.offset) })
223223
}
224224

225225
/// Search for the Memory map tag.
226226
pub fn memory_map_tag(&self) -> Option<&MemoryMapTag> {
227-
self.get_tag(TagType::Mmap)
228-
.map(|tag| tag.cast_tag::<MemoryMapTag>())
227+
self.get_tag::<MemoryMapTag, _>(TagType::Mmap)
229228
}
230229

231230
/// Get an iterator of all module tags.
@@ -235,45 +234,39 @@ impl BootInformation {
235234

236235
/// Search for the BootLoader name tag.
237236
pub fn boot_loader_name_tag(&self) -> Option<&BootLoaderNameTag> {
238-
self.get_tag(TagType::BootLoaderName)
239-
.map(|tag| tag.cast_tag::<BootLoaderNameTag>())
237+
self.get_tag::<BootLoaderNameTag, _>(TagType::BootLoaderName)
240238
}
241239

242240
/// Search for the Command line tag.
243241
pub fn command_line_tag(&self) -> Option<&CommandLineTag> {
244-
self.get_tag(TagType::Cmdline)
245-
.map(|tag| tag.cast_tag::<CommandLineTag>())
242+
self.get_tag::<CommandLineTag, _>(TagType::Cmdline)
246243
}
247244

248245
/// Search for the VBE framebuffer tag. The result is `Some(Err(e))`, if the
249246
/// framebuffer type is unknown, while the framebuffer tag is present.
250247
pub fn framebuffer_tag(&self) -> Option<Result<FramebufferTag, UnknownFramebufferType>> {
251-
self.get_tag(TagType::Framebuffer)
248+
self.get_tag::<Tag, _>(TagType::Framebuffer)
252249
.map(framebuffer::framebuffer_tag)
253250
}
254251

255252
/// Search for the EFI 32-bit SDT tag.
256253
pub fn efi_sdt_32_tag(&self) -> Option<&EFISdt32> {
257-
self.get_tag(TagType::Efi32)
258-
.map(|tag| tag.cast_tag::<EFISdt32>())
254+
self.get_tag::<EFISdt32, _>(TagType::Efi32)
259255
}
260256

261257
/// Search for the EFI 64-bit SDT tag.
262258
pub fn efi_sdt_64_tag(&self) -> Option<&EFISdt64> {
263-
self.get_tag(TagType::Efi64)
264-
.map(|tag| tag.cast_tag::<EFISdt64>())
259+
self.get_tag::<EFISdt64, _>(TagType::Efi64)
265260
}
266261

267262
/// Search for the (ACPI 1.0) RSDP tag.
268263
pub fn rsdp_v1_tag(&self) -> Option<&RsdpV1Tag> {
269-
self.get_tag(TagType::AcpiV1)
270-
.map(|tag| tag.cast_tag::<RsdpV1Tag>())
264+
self.get_tag::<RsdpV1Tag, _>(TagType::AcpiV1)
271265
}
272266

273267
/// Search for the (ACPI 2.0 or later) RSDP tag.
274268
pub fn rsdp_v2_tag(&self) -> Option<&RsdpV2Tag> {
275-
self.get_tag(TagType::AcpiV2)
276-
.map(|tag| tag.cast_tag::<RsdpV2Tag>())
269+
self.get_tag::<RsdpV2Tag, _>(TagType::AcpiV2)
277270
}
278271

279272
/// Search for the EFI Memory map tag, if the boot services were exited.
@@ -283,36 +276,30 @@ impl BootInformation {
283276
pub fn efi_memory_map_tag(&self) -> Option<&EFIMemoryMapTag> {
284277
// If the EFIBootServicesNotExited is present, then we should not use
285278
// the memory map, as it could still be in use.
286-
match self.get_tag(TagType::EfiBs) {
279+
match self.get_tag::<Tag, _>(TagType::EfiBs) {
287280
Some(_tag) => None,
288-
None => self
289-
.get_tag(TagType::EfiMmap)
290-
.map(|tag| tag.cast_tag::<EFIMemoryMapTag>()),
281+
None => self.get_tag::<EFIMemoryMapTag, _>(TagType::EfiMmap),
291282
}
292283
}
293284

294285
/// Search for the EFI 32-bit image handle pointer.
295286
pub fn efi_32_ih(&self) -> Option<&EFIImageHandle32> {
296-
self.get_tag(TagType::Efi32Ih)
297-
.map(|tag| tag.cast_tag::<EFIImageHandle32>())
287+
self.get_tag::<EFIImageHandle32, _>(TagType::Efi32Ih)
298288
}
299289

300290
/// Search for the EFI 64-bit image handle pointer.
301291
pub fn efi_64_ih(&self) -> Option<&EFIImageHandle64> {
302-
self.get_tag(TagType::Efi64Ih)
303-
.map(|tag| tag.cast_tag::<EFIImageHandle64>())
292+
self.get_tag::<EFIImageHandle64, _>(TagType::Efi64Ih)
304293
}
305294

306295
/// Search for the Image Load Base Physical Address.
307296
pub fn load_base_addr(&self) -> Option<&ImageLoadPhysAddr> {
308-
self.get_tag(TagType::LoadBaseAddr)
309-
.map(|tag| tag.cast_tag::<ImageLoadPhysAddr>())
297+
self.get_tag::<ImageLoadPhysAddr, _>(TagType::LoadBaseAddr)
310298
}
311299

312300
/// Search for the VBE information tag.
313301
pub fn vbe_info_tag(&self) -> Option<&VBEInfoTag> {
314-
self.get_tag(TagType::Vbe)
315-
.map(|tag| tag.cast_tag::<VBEInfoTag>())
302+
self.get_tag::<VBEInfoTag, _>(TagType::Vbe)
316303
}
317304

318305
fn get(&self) -> &BootInformationInner {
@@ -336,7 +323,8 @@ impl BootInformation {
336323
/// the MBI. Custom tags must be `Sized`. Hence, they are not allowed to contain a field such
337324
/// as `name: [u8]`.
338325
///
339-
/// ```rust
326+
/// **Belows example needs Rust 1.64 or newer because of std::ffi imports!**
327+
/// ```ignore
340328
/// use std::ffi::{c_char, CStr};
341329
/// use multiboot2::TagTypeId;
342330
///
@@ -349,18 +337,21 @@ impl BootInformation {
349337
/// name: u8,
350338
/// }
351339
///
352-
/// let tag = bi
353-
/// .get_tag(0x1337)
354-
/// .unwrap()
340+
/// let mbi = unsafe { multiboot2::load(0xdeadbeef).unwrap() };
341+
///
342+
/// let tag = mbi
355343
/// // type definition from end user; must be `Sized`!
356-
/// .cast_tag::<CustomTag>();
344+
/// .get_tag::<CustomTag, _>(0x1337)
345+
/// .unwrap();
357346
/// let name = &tag.name as *const u8 as *const c_char;
358347
/// let str = unsafe { CStr::from_ptr(name).to_str().unwrap() };
359348
/// assert_eq!(str, "name");
360349
/// ```
361-
pub fn get_tag(&self, typ: impl Into<TagTypeId>) -> Option<&Tag> {
350+
pub fn get_tag<Tag, TagType: Into<TagTypeId>>(&self, typ: TagType) -> Option<&Tag> {
362351
let typ = typ.into();
363-
self.tags().find(|tag| tag.typ == typ)
352+
self.tags()
353+
.find(|tag| tag.typ == typ)
354+
.map(|tag| tag.cast_tag::<Tag>())
364355
}
365356

366357
fn tags(&self) -> TagIter {
@@ -1499,6 +1490,7 @@ mod tests {
14991490
consumer(MbiLoadError::IllegalAddress)
15001491
}
15011492

1493+
#[test]
15021494
fn custom_tag() {
15031495
const CUSTOM_TAG_ID: u32 = 0x1337;
15041496

@@ -1553,7 +1545,7 @@ mod tests {
15531545
name: u8,
15541546
}
15551547

1556-
let tag = bi.get_tag(CUSTOM_TAG_ID).unwrap().cast_tag::<CustomTag>();
1548+
let tag = bi.get_tag::<CustomTag, _>(CUSTOM_TAG_ID).unwrap();
15571549

15581550
// strlen without null byte
15591551
let strlen = tag.size as usize - mem::size_of::<CommandLineTag>();
@@ -1606,10 +1598,10 @@ mod tests {
16061598
let bi = unsafe { load(addr) };
16071599
let bi = bi.unwrap();
16081600

1609-
let _tag = bi.get_tag(TagType::Cmdline).unwrap();
1601+
let _tag = bi.get_tag::<CommandLineTag, _>(TagType::Cmdline).unwrap();
16101602

1611-
let _tag = bi.get_tag(1).unwrap();
1603+
let _tag = bi.get_tag::<CommandLineTag, _>(1).unwrap();
16121604

1613-
let _tag = bi.get_tag(TagTypeId::new(1)).unwrap();
1605+
let _tag = bi.get_tag::<CommandLineTag, _>(TagTypeId::new(1)).unwrap();
16141606
}
16151607
}

0 commit comments

Comments
 (0)