diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:59:35 +0000 |
commit | d1b2d29528b7794b41e66fc2136e395a02f8529b (patch) | |
tree | a4a17504b260206dec3cf55b2dca82929a348ac2 /vendor/security-framework/src/base.rs | |
parent | Releasing progress-linux version 1.72.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.tar.xz rustc-d1b2d29528b7794b41e66fc2136e395a02f8529b.zip |
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/security-framework/src/base.rs')
-rw-r--r-- | vendor/security-framework/src/base.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/vendor/security-framework/src/base.rs b/vendor/security-framework/src/base.rs new file mode 100644 index 000000000..8c5f8e72f --- /dev/null +++ b/vendor/security-framework/src/base.rs @@ -0,0 +1,88 @@ +//! Support types for other modules. + +use core_foundation::string::CFString; +use core_foundation_sys::base::OSStatus; +use std::error; +use std::fmt; +use std::num::NonZeroI32; +use std::result; + +/// A `Result` type commonly returned by functions. +pub type Result<T, E = Error> = result::Result<T, E>; + +/// A Security Framework error. +#[derive(Copy, Clone)] +pub struct Error(NonZeroI32); + +impl fmt::Debug for Error { + #[cold] + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut builder = fmt.debug_struct("Error"); + builder.field("code", &self.0); + if let Some(message) = self.message() { + builder.field("message", &message); + } + builder.finish() + } +} + +impl Error { + /// Creates a new `Error` from a status code. + /// The code must not be zero + #[inline] + #[must_use] + pub fn from_code(code: OSStatus) -> Self { + Self(NonZeroI32::new(code).unwrap_or_else(|| NonZeroI32::new(1).unwrap())) + } + + /// Returns a string describing the current error, if available. + #[inline(always)] + #[must_use] + pub fn message(self) -> Option<String> { + self.inner_message() + } + + #[cold] + fn inner_message(self) -> Option<String> { + use core_foundation::base::TCFType; + use security_framework_sys::base::SecCopyErrorMessageString; + use std::ptr; + + unsafe { + let s = SecCopyErrorMessageString(self.code(), ptr::null_mut()); + if s.is_null() { + None + } else { + Some(CFString::wrap_under_create_rule(s).to_string()) + } + } + } + + /// Returns the code of the current error. + #[inline(always)] + #[must_use] + pub fn code(self) -> OSStatus { + self.0.get() as _ + } +} + +impl From<OSStatus> for Error { + #[inline(always)] + #[must_use] + fn from(code: OSStatus) -> Self { + Self::from_code(code) + } +} + +impl fmt::Display for Error { + #[cold] + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + if let Some(message) = self.message() { + write!(fmt, "{}", message) + } else { + write!(fmt, "error code {}", self.code()) + } + } +} + +impl error::Error for Error {} |