From 4dc61a4f12f7629ad5506acc60b1dc35fe6475c2 Mon Sep 17 00:00:00 2001 From: Chris Moylan Date: Tue, 25 Jul 2023 20:57:23 -0500 Subject: [PATCH] Implement core::error::Error for all error types --- CHANGELOG.md | 1 + uefi/src/data_types/chars.rs | 11 +++++- uefi/src/data_types/owned_strs.rs | 7 ++-- uefi/src/data_types/strs.rs | 43 +++++++++++++++++++++- uefi/src/proto/device_path/build.rs | 18 +++++++++ uefi/src/proto/driver/component_name.rs | 13 ++++++- uefi/src/proto/media/file/info.rs | 16 ++++++++ uefi/src/proto/network/pxe.rs | 29 ++++++++++++++- uefi/src/proto/string/unicode_collation.rs | 17 +++++++++ uefi/src/table/runtime.rs | 13 ++++++- 10 files changed, 159 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ed2f87d0..27742774c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - `FileSystem::copy` is now more efficient for large files. - `MpService::startup_all_aps` and `MpService::startup_this_ap` now accept an optional `event` parameter to allow non-blocking operation. +- Added `core::error::Error` implementations to all error types. ### Removed - `BootServices::memmove` and `BootServices::set_mem` have been removed, use diff --git a/uefi/src/data_types/chars.rs b/uefi/src/data_types/chars.rs index e3a6275e7..a92c57067 100644 --- a/uefi/src/data_types/chars.rs +++ b/uefi/src/data_types/chars.rs @@ -3,12 +3,21 @@ //! UEFI uses both Latin-1 and UCS-2 character encoding, this module implements //! support for the associated character types. -use core::fmt; +use core::fmt::{self, Display, Formatter}; /// Character conversion error #[derive(Clone, Copy, Debug)] pub struct CharConversionError; +impl Display for CharConversionError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for CharConversionError {} + /// A Latin-1 character #[derive(Clone, Copy, Default, Eq, PartialEq, PartialOrd, Ord)] #[repr(transparent)] diff --git a/uefi/src/data_types/owned_strs.rs b/uefi/src/data_types/owned_strs.rs index 3631725f5..8e673c2f2 100644 --- a/uefi/src/data_types/owned_strs.rs +++ b/uefi/src/data_types/owned_strs.rs @@ -7,7 +7,8 @@ use alloc::borrow::{Borrow, ToOwned}; use alloc::string::String; use alloc::vec; use alloc::vec::Vec; -use core::{fmt, ops}; +use core::fmt::{self, Display, Formatter}; +use core::ops; /// Error returned by [`CString16::try_from::<&str>`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -18,8 +19,8 @@ pub enum FromStrError { InteriorNul, } -impl fmt::Display for FromStrError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl Display for FromStrError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!( f, "UCS-2 Conversion Error: {}", diff --git a/uefi/src/data_types/strs.rs b/uefi/src/data_types/strs.rs index 875f1c731..4cfd2f7c4 100644 --- a/uefi/src/data_types/strs.rs +++ b/uefi/src/data_types/strs.rs @@ -3,10 +3,11 @@ use super::UnalignedSlice; use crate::polyfill::maybe_uninit_slice_assume_init_ref; use core::borrow::Borrow; use core::ffi::CStr; +use core::fmt::{self, Display, Formatter}; use core::iter::Iterator; use core::mem::MaybeUninit; use core::result::Result; -use core::{fmt, slice}; +use core::slice; #[cfg(feature = "alloc")] use super::CString16; @@ -24,6 +25,19 @@ pub enum FromSliceWithNulError { NotNulTerminated, } +impl Display for FromSliceWithNulError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidChar(usize) => write!(f, "invalid character at index {}", usize), + Self::InteriorNul(usize) => write!(f, "interior null character at index {}", usize), + Self::NotNulTerminated => write!(f, "not null-terminated"), + } + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for FromSliceWithNulError {} + /// Error returned by [`CStr16::from_unaligned_slice`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum UnalignedCStr16Error { @@ -41,6 +55,20 @@ pub enum UnalignedCStr16Error { BufferTooSmall, } +impl Display for UnalignedCStr16Error { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidChar(usize) => write!(f, "invalid character at index {}", usize), + Self::InteriorNul(usize) => write!(f, "interior null character at index {}", usize), + Self::NotNulTerminated => write!(f, "not null-terminated"), + Self::BufferTooSmall => write!(f, "buffer too small"), + } + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for UnalignedCStr16Error {} + /// Error returned by [`CStr16::from_str_with_buf`]. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum FromStrWithBufError { @@ -55,6 +83,19 @@ pub enum FromStrWithBufError { BufferTooSmall, } +impl Display for FromStrWithBufError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::InvalidChar(usize) => write!(f, "invalid character at index {}", usize), + Self::InteriorNul(usize) => write!(f, "interior null character at index {}", usize), + Self::BufferTooSmall => write!(f, "buffer too small"), + } + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for FromStrWithBufError {} + /// A null-terminated Latin-1 string. /// /// This type is largely inspired by [`core::ffi::CStr`] with the exception that all characters are diff --git a/uefi/src/proto/device_path/build.rs b/uefi/src/proto/device_path/build.rs index 03e24b75e..3a09b2451 100644 --- a/uefi/src/proto/device_path/build.rs +++ b/uefi/src/proto/device_path/build.rs @@ -9,6 +9,7 @@ pub use crate::proto::device_path::device_path_gen::build::*; use crate::polyfill::{maybe_uninit_slice_as_mut_ptr, maybe_uninit_slice_assume_init_ref}; use crate::proto::device_path::{DevicePath, DevicePathNode}; +use core::fmt::{self, Display, Formatter}; use core::mem::MaybeUninit; #[cfg(feature = "alloc")] @@ -174,6 +175,23 @@ pub enum BuildError { UnexpectedEndEntire, } +impl Display for BuildError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::BufferTooSmall => "a node was too big to fit in remaining buffer space", + Self::NodeTooBig => "a node was too big", + Self::UnexpectedEndEntire => "unexpected END_ENTIRE", + } + ) + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for BuildError {} + /// Trait for types that can be used to build a node via /// [`DevicePathBuilder::push`]. /// diff --git a/uefi/src/proto/driver/component_name.rs b/uefi/src/proto/driver/component_name.rs index bce32ed87..bc1d90e7f 100644 --- a/uefi/src/proto/driver/component_name.rs +++ b/uefi/src/proto/driver/component_name.rs @@ -7,7 +7,7 @@ use crate::proto::unsafe_protocol; use crate::table::boot::{BootServices, ScopedProtocol}; use crate::{CStr16, Error, Handle, Result, Status, StatusExt}; -use core::fmt::{Debug, Formatter}; +use core::fmt::{self, Debug, Display, Formatter}; use core::{ptr, slice}; use uefi_raw::protocol::driver::ComponentName2Protocol; @@ -238,6 +238,17 @@ pub enum LanguageError { }, } +impl Display for LanguageError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::Ascii { index } => write!(f, "invalid character at index: {}", index), + } + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for LanguageError {} + #[derive(Debug, PartialEq)] enum LanguageIterKind { V1, diff --git a/uefi/src/proto/media/file/info.rs b/uefi/src/proto/media/file/info.rs index 286962b81..10cd7bb6e 100644 --- a/uefi/src/proto/media/file/info.rs +++ b/uefi/src/proto/media/file/info.rs @@ -3,6 +3,7 @@ use crate::data_types::Align; use crate::table::runtime::Time; use crate::{guid, CStr16, Char16, Guid, Identify}; use core::ffi::c_void; +use core::fmt::{self, Display, Formatter}; use core::{mem, ptr}; use ptr_meta::Pointee; @@ -124,6 +125,21 @@ pub enum FileInfoCreationError { InsufficientStorage(usize), } +impl Display for FileInfoCreationError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::InsufficientStorage(bytes) => write!( + f, + "provided buffer was too small. need at least {} bytes", + bytes + ), + } + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for FileInfoCreationError {} + /// Generic file information /// /// The following rules apply when using this struct with `set_info()`: diff --git a/uefi/src/proto/network/pxe.rs b/uefi/src/proto/network/pxe.rs index 979b4ed54..11fb28a21 100644 --- a/uefi/src/proto/network/pxe.rs +++ b/uefi/src/proto/network/pxe.rs @@ -1,7 +1,7 @@ //! PXE Base Code protocol. use core::ffi::c_void; -use core::fmt::{Debug, Formatter}; +use core::fmt::{self, Debug, Display, Formatter}; use core::iter::from_fn; use core::mem::MaybeUninit; use core::ptr::{null, null_mut}; @@ -1240,6 +1240,15 @@ pub struct IcmpError { pub data: [u8; 494], } +impl Display for IcmpError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for IcmpError {} + /// Corresponds to the anonymous union inside /// `EFI_PXE_BASE_CODE_ICMP_ERROR` in the C API. #[repr(C)] @@ -1278,6 +1287,15 @@ pub struct TftpError { pub error_string: [u8; 127], } +impl Display for TftpError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for TftpError {} + /// Returned by [`BaseCode::tftp_read_dir`]. #[allow(missing_docs)] #[derive(Debug)] @@ -1311,3 +1329,12 @@ pub struct MtftpFileInfo<'a> { /// [`BaseCode::tftp_read_dir`] or [`BaseCode::mtftp_read_dir`]. #[derive(Clone, Copy, Debug)] pub struct ReadDirParseError; + +impl Display for ReadDirParseError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for ReadDirParseError {} diff --git a/uefi/src/proto/string/unicode_collation.rs b/uefi/src/proto/string/unicode_collation.rs index c008f3f31..da80aa137 100644 --- a/uefi/src/proto/string/unicode_collation.rs +++ b/uefi/src/proto/string/unicode_collation.rs @@ -6,6 +6,7 @@ use crate::data_types::{CStr16, CStr8, Char16, Char8}; use crate::proto::unsafe_protocol; use core::cmp::Ordering; +use core::fmt::{self, Display, Formatter}; /// The Unicode Collation Protocol. /// @@ -159,3 +160,19 @@ pub enum StrConversionError { /// The buffer given is too small to hold the string. BufferTooSmall, } + +impl Display for StrConversionError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + match self { + Self::ConversionFailed => "conversion failed", + Self::BufferTooSmall => "buffer too small", + } + ) + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for StrConversionError {} diff --git a/uefi/src/table/runtime.rs b/uefi/src/table/runtime.rs index 68ec0bdff..1c5901c73 100644 --- a/uefi/src/table/runtime.rs +++ b/uefi/src/table/runtime.rs @@ -3,9 +3,9 @@ use super::Revision; use crate::table::boot::MemoryDescriptor; use crate::{CStr16, Error, Result, Status, StatusExt}; -use core::fmt::{Debug, Formatter}; +use core::fmt::{self, Debug, Display, Formatter}; use core::mem::MaybeUninit; -use core::{fmt, ptr}; +use core::ptr; pub use uefi_raw::table::runtime::{ ResetType, TimeCapabilities, VariableAttributes, VariableVendor, @@ -352,6 +352,15 @@ pub struct TimeParams { #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)] pub struct TimeError; +impl Display for TimeError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{self:?}") + } +} + +#[cfg(feature = "unstable")] +impl core::error::Error for TimeError {} + impl Time { /// Unspecified Timezone/local time. const UNSPECIFIED_TIMEZONE: i16 = uefi_raw::time::Time::UNSPECIFIED_TIMEZONE;