1 //! Module for the [`BootPolicy`] helper type. 2 3 use core::fmt::{Display, Formatter}; 4 5 /// Errors that can happen when working with [`BootPolicy`]. 6 #[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Ord)] 7 pub enum BootPolicyError { 8 /// Only `0` and `1` are valid integers, all other values are undefined. 9 InvalidInteger(u8), 10 } 11 12 impl Display for BootPolicyError { fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result13 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 14 let s = match self { 15 Self::InvalidInteger(_) => { 16 "Only `0` and `1` are valid integers, all other values are undefined." 17 } 18 }; 19 f.write_str(s) 20 } 21 } 22 23 #[cfg(feature = "unstable")] 24 impl core::error::Error for BootPolicyError {} 25 26 /// The UEFI boot policy is a property that influences the behaviour of 27 /// various UEFI functions that load files (typically UEFI images). 28 /// 29 /// This type is not ABI compatible. On the ABI level, this is an UEFI 30 /// boolean. 31 #[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] 32 pub enum BootPolicy { 33 /// Indicates that the request originates from the boot manager, and that 34 /// the boot manager is attempting to load the provided `file_path` as a 35 /// boot selection. 36 /// 37 /// Boot selection refers to what a user has chosen in the (GUI) boot menu. 38 /// 39 /// This corresponds to the `TRUE` value in the UEFI spec. 40 BootSelection, 41 /// The provided `file_path` must match an exact file to be loaded. 42 /// 43 /// This corresponds to the `FALSE` value in the UEFI spec. 44 #[default] 45 ExactMatch, 46 } 47 48 impl From<BootPolicy> for bool { from(value: BootPolicy) -> Self49 fn from(value: BootPolicy) -> Self { 50 match value { 51 BootPolicy::BootSelection => true, 52 BootPolicy::ExactMatch => false, 53 } 54 } 55 } 56 57 impl From<bool> for BootPolicy { from(value: bool) -> Self58 fn from(value: bool) -> Self { 59 match value { 60 true => Self::BootSelection, 61 false => Self::ExactMatch, 62 } 63 } 64 } 65 66 impl From<BootPolicy> for u8 { from(value: BootPolicy) -> Self67 fn from(value: BootPolicy) -> Self { 68 match value { 69 BootPolicy::BootSelection => 1, 70 BootPolicy::ExactMatch => 0, 71 } 72 } 73 } 74 75 impl TryFrom<u8> for BootPolicy { 76 type Error = BootPolicyError; try_from(value: u8) -> Result<Self, Self::Error>77 fn try_from(value: u8) -> Result<Self, Self::Error> { 78 match value { 79 0 => Ok(Self::ExactMatch), 80 1 => Ok(Self::BootSelection), 81 err => Err(Self::Error::InvalidInteger(err)), 82 } 83 } 84 } 85 86 #[cfg(test)] 87 mod tests { 88 use super::*; 89 90 #[test] boot_policy()91 fn boot_policy() { 92 assert_eq!(bool::from(BootPolicy::ExactMatch), false); 93 assert_eq!(bool::from(BootPolicy::BootSelection), true); 94 95 assert_eq!(BootPolicy::from(false), BootPolicy::ExactMatch); 96 assert_eq!(BootPolicy::from(true), BootPolicy::BootSelection); 97 98 assert_eq!(u8::from(BootPolicy::ExactMatch), 0); 99 assert_eq!(u8::from(BootPolicy::BootSelection), 1); 100 101 assert_eq!(BootPolicy::try_from(0), Ok(BootPolicy::ExactMatch)); 102 assert_eq!(BootPolicy::try_from(1), Ok(BootPolicy::BootSelection)); 103 assert_eq!( 104 BootPolicy::try_from(2), 105 Err(BootPolicyError::InvalidInteger(2)) 106 ); 107 } 108 } 109