1 use super::{Error, Result}; 2 use core::fmt::Debug; 3 4 pub use uefi_raw::Status; 5 6 /// Extension trait which provides some convenience methods for [`Status`]. 7 pub trait StatusExt { 8 /// Converts this status code into a [`uefi::Result`]. 9 /// 10 /// If the status does not indicate success, the status representing the specific error 11 /// code is embedded into the `Err` variant of type [`uefi::Error`]. to_result(self) -> Result12 fn to_result(self) -> Result; 13 14 /// Converts this status code into a [`uefi::Result`] with a given `Ok` value. 15 /// 16 /// If the status does not indicate success, the status representing the specific error 17 /// code is embedded into the `Err` variant of type [`uefi::Error`]. to_result_with_val<T>(self, val: impl FnOnce() -> T) -> Result<T, ()>18 fn to_result_with_val<T>(self, val: impl FnOnce() -> T) -> Result<T, ()>; 19 20 /// Converts this status code into a [`uefi::Result`] with a given `Err` payload. 21 /// 22 /// If the status does not indicate success, the status representing the specific error 23 /// code is embedded into the `Err` variant of type [`uefi::Error`]. to_result_with_err<ErrData: Debug>( self, err: impl FnOnce(Status) -> ErrData, ) -> Result<(), ErrData>24 fn to_result_with_err<ErrData: Debug>( 25 self, 26 err: impl FnOnce(Status) -> ErrData, 27 ) -> Result<(), ErrData>; 28 29 /// Convert this status code into a result with a given `Ok` value and `Err` payload. 30 /// 31 /// If the status does not indicate success, the status representing the specific error 32 /// code is embedded into the `Err` variant of type [`uefi::Error`]. to_result_with<T, ErrData: Debug>( self, val: impl FnOnce() -> T, err: impl FnOnce(Status) -> ErrData, ) -> Result<T, ErrData>33 fn to_result_with<T, ErrData: Debug>( 34 self, 35 val: impl FnOnce() -> T, 36 err: impl FnOnce(Status) -> ErrData, 37 ) -> Result<T, ErrData>; 38 } 39 40 impl StatusExt for Status { 41 #[inline] to_result(self) -> Result42 fn to_result(self) -> Result { 43 if self.is_success() { 44 Ok(()) 45 } else { 46 Err(self.into()) 47 } 48 } 49 50 #[inline] to_result_with_val<T>(self, val: impl FnOnce() -> T) -> Result<T, ()>51 fn to_result_with_val<T>(self, val: impl FnOnce() -> T) -> Result<T, ()> { 52 if self.is_success() { 53 Ok(val()) 54 } else { 55 Err(self.into()) 56 } 57 } 58 59 #[inline] to_result_with_err<ErrData: Debug>( self, err: impl FnOnce(Self) -> ErrData, ) -> Result<(), ErrData>60 fn to_result_with_err<ErrData: Debug>( 61 self, 62 err: impl FnOnce(Self) -> ErrData, 63 ) -> Result<(), ErrData> { 64 if self.is_success() { 65 Ok(()) 66 } else { 67 Err(Error::new(self, err(self))) 68 } 69 } 70 71 #[inline] to_result_with<T, ErrData: Debug>( self, val: impl FnOnce() -> T, err: impl FnOnce(Self) -> ErrData, ) -> Result<T, ErrData>72 fn to_result_with<T, ErrData: Debug>( 73 self, 74 val: impl FnOnce() -> T, 75 err: impl FnOnce(Self) -> ErrData, 76 ) -> Result<T, ErrData> { 77 if self.is_success() { 78 Ok(val()) 79 } else { 80 Err(Error::new(self, err(self))) 81 } 82 } 83 } 84 85 #[cfg(test)] 86 mod tests { 87 use super::*; 88 89 #[test] test_status_to_result()90 fn test_status_to_result() { 91 assert!(Status::SUCCESS.to_result().is_ok()); 92 assert!(Status::WARN_DELETE_FAILURE.to_result().is_err()); 93 assert!(Status::BUFFER_TOO_SMALL.to_result().is_err()); 94 95 assert_eq!(Status::SUCCESS.to_result_with_val(|| 123).unwrap(), 123); 96 assert!(Status::WARN_DELETE_FAILURE 97 .to_result_with_val(|| 123) 98 .is_err()); 99 assert!(Status::BUFFER_TOO_SMALL.to_result_with_val(|| 123).is_err()); 100 101 assert!(Status::SUCCESS.to_result_with_err(|_| 123).is_ok()); 102 assert_eq!( 103 *Status::WARN_DELETE_FAILURE 104 .to_result_with_err(|_| 123) 105 .unwrap_err() 106 .data(), 107 123 108 ); 109 assert_eq!( 110 *Status::BUFFER_TOO_SMALL 111 .to_result_with_err(|_| 123) 112 .unwrap_err() 113 .data(), 114 123 115 ); 116 117 assert_eq!( 118 Status::SUCCESS.to_result_with(|| 123, |_| 456).unwrap(), 119 123 120 ); 121 assert_eq!( 122 *Status::WARN_DELETE_FAILURE 123 .to_result_with(|| 123, |_| 456) 124 .unwrap_err() 125 .data(), 126 456 127 ); 128 assert_eq!( 129 *Status::BUFFER_TOO_SMALL 130 .to_result_with(|| 123, |_| 456) 131 .unwrap_err() 132 .data(), 133 456 134 ); 135 } 136 } 137