use core::{error, ffi::c_int, fmt};
use darwin_kperf_sys::kperfdata;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FrameworkErrorKind {
None,
InvalidArgument,
OutOfMemory,
Io,
BufferTooSmall,
CurrentSystemUnknown,
DatabasePathInvalid,
DatabaseNotFound,
DatabaseArchitectureUnsupported,
DatabaseVersionUnsupported,
DatabaseCorrupt,
EventNotFound,
ConflictingEvents,
AllCountersMustBeForced,
EventUnavailable,
CheckErrno,
Other(c_int),
}
impl FrameworkErrorKind {
const fn from_code(code: c_int) -> Self {
match code {
kperfdata::KPEP_CONFIG_ERROR_NONE => Self::None,
kperfdata::KPEP_CONFIG_ERROR_INVALID_ARGUMENT => Self::InvalidArgument,
kperfdata::KPEP_CONFIG_ERROR_OUT_OF_MEMORY => Self::OutOfMemory,
kperfdata::KPEP_CONFIG_ERROR_IO => Self::Io,
kperfdata::KPEP_CONFIG_ERROR_BUFFER_TOO_SMALL => Self::BufferTooSmall,
kperfdata::KPEP_CONFIG_ERROR_CUR_SYSTEM_UNKNOWN => Self::CurrentSystemUnknown,
kperfdata::KPEP_CONFIG_ERROR_DB_PATH_INVALID => Self::DatabasePathInvalid,
kperfdata::KPEP_CONFIG_ERROR_DB_NOT_FOUND => Self::DatabaseNotFound,
kperfdata::KPEP_CONFIG_ERROR_DB_ARCH_UNSUPPORTED => {
Self::DatabaseArchitectureUnsupported
}
kperfdata::KPEP_CONFIG_ERROR_DB_VERSION_UNSUPPORTED => Self::DatabaseVersionUnsupported,
kperfdata::KPEP_CONFIG_ERROR_DB_CORRUPT => Self::DatabaseCorrupt,
kperfdata::KPEP_CONFIG_ERROR_EVENT_NOT_FOUND => Self::EventNotFound,
kperfdata::KPEP_CONFIG_ERROR_CONFLICTING_EVENTS => Self::ConflictingEvents,
kperfdata::KPEP_CONFIG_ERROR_COUNTERS_NOT_FORCED => Self::AllCountersMustBeForced,
kperfdata::KPEP_CONFIG_ERROR_EVENT_UNAVAILABLE => Self::EventUnavailable,
kperfdata::KPEP_CONFIG_ERROR_ERRNO => Self::CheckErrno,
_ => Self::Other(code),
}
}
const fn as_str(self) -> &'static str {
match self {
Self::None => "success",
Self::InvalidArgument => "invalid argument",
Self::OutOfMemory => "out of memory",
Self::Io => "I/O error",
Self::BufferTooSmall => "buffer too small",
Self::CurrentSystemUnknown => "current system unknown",
Self::DatabasePathInvalid => "database path invalid",
Self::DatabaseNotFound => "database not found",
Self::DatabaseArchitectureUnsupported => "database architecture unsupported",
Self::DatabaseVersionUnsupported => "database version unsupported",
Self::DatabaseCorrupt => "database corrupt",
Self::EventNotFound => "event not found",
Self::ConflictingEvents => "conflicting events",
Self::AllCountersMustBeForced => "all counters must be forced",
Self::EventUnavailable => "event unavailable",
Self::CheckErrno => "check errno",
Self::Other(_) => "unknown error",
}
}
}
impl fmt::Display for FrameworkErrorKind {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.write_str(self.as_str())
}
}
pub struct FrameworkError {
code: c_int,
kind: FrameworkErrorKind,
}
impl FrameworkError {
#[must_use]
pub const fn from_code(code: c_int) -> Self {
Self {
code,
kind: FrameworkErrorKind::from_code(code),
}
}
#[must_use]
pub const fn kind(&self) -> FrameworkErrorKind {
self.kind
}
}
impl fmt::Debug for FrameworkError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_struct("Error")
.field("kind", &self.kind)
.finish_non_exhaustive()
}
}
impl fmt::Display for FrameworkError {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(fmt, "kpep error {}: {}", self.code, self.kind)
}
}
impl error::Error for FrameworkError {}