use core::fmt;
use ruvix_types::KernelError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PhysMemError {
OutOfMemory,
AllocationTooLarge,
ZeroAllocation,
UnalignedAddress,
AddressOutOfRange,
NotAllocated,
SizeMismatch,
NotInitialized,
InvalidOrder,
InternalCorruption,
}
impl PhysMemError {
#[inline]
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::OutOfMemory => "Out of physical memory",
Self::AllocationTooLarge => "Allocation size exceeds maximum block size",
Self::ZeroAllocation => "Cannot allocate zero pages",
Self::UnalignedAddress => "Address is not page-aligned",
Self::AddressOutOfRange => "Address is outside managed memory range",
Self::NotAllocated => "Block is not allocated (possible double-free)",
Self::SizeMismatch => "Free size does not match allocation size",
Self::NotInitialized => "Allocator has not been initialized",
Self::InvalidOrder => "Invalid block order specified",
Self::InternalCorruption => "Internal allocator corruption detected",
}
}
#[inline]
#[must_use]
pub const fn to_kernel_error(self) -> KernelError {
match self {
Self::OutOfMemory | Self::AllocationTooLarge => KernelError::OutOfMemory,
Self::ZeroAllocation | Self::InvalidOrder => KernelError::InvalidArgument,
Self::UnalignedAddress | Self::AddressOutOfRange => KernelError::InvalidArgument,
Self::NotAllocated | Self::SizeMismatch => KernelError::InvalidArgument,
Self::NotInitialized => KernelError::NotPermitted,
Self::InternalCorruption => KernelError::InternalError,
}
}
}
impl fmt::Display for PhysMemError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl From<PhysMemError> for KernelError {
#[inline]
fn from(err: PhysMemError) -> Self {
err.to_kernel_error()
}
}
#[cfg(feature = "std")]
impl std::error::Error for PhysMemError {}
#[cfg(test)]
mod tests {
extern crate alloc;
use alloc::format;
use super::*;
#[test]
fn test_error_as_str() {
assert_eq!(PhysMemError::OutOfMemory.as_str(), "Out of physical memory");
assert_eq!(
PhysMemError::AllocationTooLarge.as_str(),
"Allocation size exceeds maximum block size"
);
assert_eq!(
PhysMemError::ZeroAllocation.as_str(),
"Cannot allocate zero pages"
);
assert_eq!(
PhysMemError::UnalignedAddress.as_str(),
"Address is not page-aligned"
);
}
#[test]
fn test_to_kernel_error() {
assert_eq!(
PhysMemError::OutOfMemory.to_kernel_error(),
KernelError::OutOfMemory
);
assert_eq!(
PhysMemError::AllocationTooLarge.to_kernel_error(),
KernelError::OutOfMemory
);
assert_eq!(
PhysMemError::ZeroAllocation.to_kernel_error(),
KernelError::InvalidArgument
);
assert_eq!(
PhysMemError::InternalCorruption.to_kernel_error(),
KernelError::InternalError
);
}
#[test]
fn test_into_kernel_error() {
let err: KernelError = PhysMemError::OutOfMemory.into();
assert_eq!(err, KernelError::OutOfMemory);
}
#[test]
fn test_display() {
assert_eq!(format!("{}", PhysMemError::OutOfMemory), "Out of physical memory");
}
#[test]
fn test_debug() {
assert_eq!(format!("{:?}", PhysMemError::OutOfMemory), "OutOfMemory");
}
}