apple_security_framework/
base.rs1use std::{error, fmt, num::NonZeroI32, result};
4
5use core_foundation::string::CFString;
6use core_foundation_sys::base::OSStatus;
7
8pub type Result<T, E = Error> = result::Result<T, E>;
10
11#[derive(Copy, Clone)]
13pub struct Error(NonZeroI32);
14
15impl fmt::Debug for Error {
16 #[cold]
17 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
18 let mut builder = fmt.debug_struct("Error");
19 builder.field("code", &self.0);
20 if let Some(message) = self.message() {
21 builder.field("message", &message);
22 }
23 builder.finish()
24 }
25}
26
27impl Error {
28 #[inline]
31 #[must_use]
32 pub fn from_code(code: OSStatus) -> Self {
33 Self(NonZeroI32::new(code).unwrap_or_else(|| NonZeroI32::new(1).unwrap()))
34 }
35
36 #[inline(always)]
38 #[must_use]
39 pub fn message(self) -> Option<String> {
40 self.inner_message()
41 }
42
43 #[cold]
44 fn inner_message(self) -> Option<String> {
45 use std::ptr;
46
47 use core_foundation::base::TCFType;
48 use security_framework_sys::base::SecCopyErrorMessageString;
49
50 unsafe {
51 let s = SecCopyErrorMessageString(self.code(), ptr::null_mut());
52 if s.is_null() {
53 None
54 } else {
55 Some(CFString::wrap_under_create_rule(s).to_string())
56 }
57 }
58 }
59
60 #[inline(always)]
62 #[must_use]
63 pub fn code(self) -> OSStatus {
64 self.0.get() as _
65 }
66}
67
68impl From<OSStatus> for Error {
69 #[inline(always)]
70 #[must_use]
71 fn from(code: OSStatus) -> Self {
72 Self::from_code(code)
73 }
74}
75
76impl fmt::Display for Error {
77 #[cold]
78 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
79 if let Some(message) = self.message() {
80 write!(fmt, "{}", message)
81 } else {
82 write!(fmt, "error code {}", self.code())
83 }
84 }
85}
86
87impl error::Error for Error {}