use super::{Error, Result}; use core::fmt::Debug; pub use uefi_raw::Status; /// Extension trait which provides some convenience methods for [`Status`]. pub trait StatusExt { /// Converts this status code into a [`uefi::Result`]. /// /// If the status does not indicate success, the status representing the specific error /// code is embedded into the `Err` variant of type [`uefi::Error`]. fn to_result(self) -> Result; /// Converts this status code into a [`uefi::Result`] with a given `Ok` value. /// /// If the status does not indicate success, the status representing the specific error /// code is embedded into the `Err` variant of type [`uefi::Error`]. fn to_result_with_val(self, val: impl FnOnce() -> T) -> Result; /// Converts this status code into a [`uefi::Result`] with a given `Err` payload. /// /// If the status does not indicate success, the status representing the specific error /// code is embedded into the `Err` variant of type [`uefi::Error`]. fn to_result_with_err( self, err: impl FnOnce(Status) -> ErrData, ) -> Result<(), ErrData>; /// Convert this status code into a result with a given `Ok` value and `Err` payload. /// /// If the status does not indicate success, the status representing the specific error /// code is embedded into the `Err` variant of type [`uefi::Error`]. fn to_result_with( self, val: impl FnOnce() -> T, err: impl FnOnce(Status) -> ErrData, ) -> Result; } impl StatusExt for Status { #[inline] fn to_result(self) -> Result { if self.is_success() { Ok(()) } else { Err(self.into()) } } #[inline] fn to_result_with_val(self, val: impl FnOnce() -> T) -> Result { if self.is_success() { Ok(val()) } else { Err(self.into()) } } #[inline] fn to_result_with_err( self, err: impl FnOnce(Self) -> ErrData, ) -> Result<(), ErrData> { if self.is_success() { Ok(()) } else { Err(Error::new(self, err(self))) } } #[inline] fn to_result_with( self, val: impl FnOnce() -> T, err: impl FnOnce(Self) -> ErrData, ) -> Result { if self.is_success() { Ok(val()) } else { Err(Error::new(self, err(self))) } } } #[cfg(test)] mod tests { use super::*; #[test] fn test_status_to_result() { assert!(Status::SUCCESS.to_result().is_ok()); assert!(Status::WARN_DELETE_FAILURE.to_result().is_err()); assert!(Status::BUFFER_TOO_SMALL.to_result().is_err()); assert_eq!(Status::SUCCESS.to_result_with_val(|| 123).unwrap(), 123); assert!(Status::WARN_DELETE_FAILURE .to_result_with_val(|| 123) .is_err()); assert!(Status::BUFFER_TOO_SMALL.to_result_with_val(|| 123).is_err()); assert!(Status::SUCCESS.to_result_with_err(|_| 123).is_ok()); assert_eq!( *Status::WARN_DELETE_FAILURE .to_result_with_err(|_| 123) .unwrap_err() .data(), 123 ); assert_eq!( *Status::BUFFER_TOO_SMALL .to_result_with_err(|_| 123) .unwrap_err() .data(), 123 ); assert_eq!( Status::SUCCESS.to_result_with(|| 123, |_| 456).unwrap(), 123 ); assert_eq!( *Status::WARN_DELETE_FAILURE .to_result_with(|| 123, |_| 456) .unwrap_err() .data(), 456 ); assert_eq!( *Status::BUFFER_TOO_SMALL .to_result_with(|| 123, |_| 456) .unwrap_err() .data(), 456 ); } }