@@ -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