@@ -218,14 +218,13 @@ impl BootInformation {
218
218
219
219
/// Search for the ELF Sections tag.
220
220
pub fn elf_sections_tag ( & self ) -> Option < ElfSectionsTag > {
221
- self . get_tag ( TagType :: ElfSections )
221
+ self . get_tag :: < Tag , _ > ( TagType :: ElfSections )
222
222
. map ( |tag| unsafe { elf_sections:: elf_sections_tag ( tag, self . offset ) } )
223
223
}
224
224
225
225
/// Search for the Memory map tag.
226
226
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 )
229
228
}
230
229
231
230
/// Get an iterator of all module tags.
@@ -235,45 +234,39 @@ impl BootInformation {
235
234
236
235
/// Search for the BootLoader name tag.
237
236
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 )
240
238
}
241
239
242
240
/// Search for the Command line tag.
243
241
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 )
246
243
}
247
244
248
245
/// Search for the VBE framebuffer tag. The result is `Some(Err(e))`, if the
249
246
/// framebuffer type is unknown, while the framebuffer tag is present.
250
247
pub fn framebuffer_tag ( & self ) -> Option < Result < FramebufferTag , UnknownFramebufferType > > {
251
- self . get_tag ( TagType :: Framebuffer )
248
+ self . get_tag :: < Tag , _ > ( TagType :: Framebuffer )
252
249
. map ( framebuffer:: framebuffer_tag)
253
250
}
254
251
255
252
/// Search for the EFI 32-bit SDT tag.
256
253
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 )
259
255
}
260
256
261
257
/// Search for the EFI 64-bit SDT tag.
262
258
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 )
265
260
}
266
261
267
262
/// Search for the (ACPI 1.0) RSDP tag.
268
263
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 )
271
265
}
272
266
273
267
/// Search for the (ACPI 2.0 or later) RSDP tag.
274
268
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 )
277
270
}
278
271
279
272
/// Search for the EFI Memory map tag, if the boot services were exited.
@@ -283,36 +276,30 @@ impl BootInformation {
283
276
pub fn efi_memory_map_tag ( & self ) -> Option < & EFIMemoryMapTag > {
284
277
// If the EFIBootServicesNotExited is present, then we should not use
285
278
// 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 ) {
287
280
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 ) ,
291
282
}
292
283
}
293
284
294
285
/// Search for the EFI 32-bit image handle pointer.
295
286
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 )
298
288
}
299
289
300
290
/// Search for the EFI 64-bit image handle pointer.
301
291
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 )
304
293
}
305
294
306
295
/// Search for the Image Load Base Physical Address.
307
296
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 )
310
298
}
311
299
312
300
/// Search for the VBE information tag.
313
301
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 )
316
303
}
317
304
318
305
fn get ( & self ) -> & BootInformationInner {
@@ -336,7 +323,8 @@ impl BootInformation {
336
323
/// the MBI. Custom tags must be `Sized`. Hence, they are not allowed to contain a field such
337
324
/// as `name: [u8]`.
338
325
///
339
- /// ```rust
326
+ /// **Belows example needs Rust 1.64 or newer because of std::ffi imports!**
327
+ /// ```ignore
340
328
/// use std::ffi::{c_char, CStr};
341
329
/// use multiboot2::TagTypeId;
342
330
///
@@ -349,18 +337,21 @@ impl BootInformation {
349
337
/// name: u8,
350
338
/// }
351
339
///
352
- /// let tag = bi
353
- /// .get_tag(0x1337)
354
- /// .unwrap()
340
+ /// let mbi = unsafe { multiboot2::load(0xdeadbeef).unwrap() };
341
+ ///
342
+ /// let tag = mbi
355
343
/// // type definition from end user; must be `Sized`!
356
- /// .cast_tag::<CustomTag>();
344
+ /// .get_tag::<CustomTag, _>(0x1337)
345
+ /// .unwrap();
357
346
/// let name = &tag.name as *const u8 as *const c_char;
358
347
/// let str = unsafe { CStr::from_ptr(name).to_str().unwrap() };
359
348
/// assert_eq!(str, "name");
360
349
/// ```
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 > {
362
351
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 > ( ) )
364
355
}
365
356
366
357
fn tags ( & self ) -> TagIter {
@@ -1499,6 +1490,7 @@ mod tests {
1499
1490
consumer ( MbiLoadError :: IllegalAddress )
1500
1491
}
1501
1492
1493
+ #[ test]
1502
1494
fn custom_tag ( ) {
1503
1495
const CUSTOM_TAG_ID : u32 = 0x1337 ;
1504
1496
@@ -1553,7 +1545,7 @@ mod tests {
1553
1545
name : u8 ,
1554
1546
}
1555
1547
1556
- let tag = bi. get_tag ( CUSTOM_TAG_ID ) . unwrap ( ) . cast_tag :: < CustomTag > ( ) ;
1548
+ let tag = bi. get_tag :: < CustomTag , _ > ( CUSTOM_TAG_ID ) . unwrap ( ) ;
1557
1549
1558
1550
// strlen without null byte
1559
1551
let strlen = tag. size as usize - mem:: size_of :: < CommandLineTag > ( ) ;
@@ -1606,10 +1598,10 @@ mod tests {
1606
1598
let bi = unsafe { load ( addr) } ;
1607
1599
let bi = bi. unwrap ( ) ;
1608
1600
1609
- let _tag = bi. get_tag ( TagType :: Cmdline ) . unwrap ( ) ;
1601
+ let _tag = bi. get_tag :: < CommandLineTag , _ > ( TagType :: Cmdline ) . unwrap ( ) ;
1610
1602
1611
- let _tag = bi. get_tag ( 1 ) . unwrap ( ) ;
1603
+ let _tag = bi. get_tag :: < CommandLineTag , _ > ( 1 ) . unwrap ( ) ;
1612
1604
1613
- let _tag = bi. get_tag ( TagTypeId :: new ( 1 ) ) . unwrap ( ) ;
1605
+ let _tag = bi. get_tag :: < CommandLineTag , _ > ( TagTypeId :: new ( 1 ) ) . unwrap ( ) ;
1614
1606
}
1615
1607
}
0 commit comments