1use core::fmt;
6
7use ruvix_types::KernelError;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum PhysMemError {
15 OutOfMemory,
17
18 AllocationTooLarge,
22
23 ZeroAllocation,
25
26 UnalignedAddress,
28
29 AddressOutOfRange,
31
32 NotAllocated,
37
38 SizeMismatch,
42
43 NotInitialized,
45
46 InvalidOrder,
48
49 InternalCorruption,
53}
54
55impl PhysMemError {
56 #[inline]
58 #[must_use]
59 pub const fn as_str(&self) -> &'static str {
60 match self {
61 Self::OutOfMemory => "Out of physical memory",
62 Self::AllocationTooLarge => "Allocation size exceeds maximum block size",
63 Self::ZeroAllocation => "Cannot allocate zero pages",
64 Self::UnalignedAddress => "Address is not page-aligned",
65 Self::AddressOutOfRange => "Address is outside managed memory range",
66 Self::NotAllocated => "Block is not allocated (possible double-free)",
67 Self::SizeMismatch => "Free size does not match allocation size",
68 Self::NotInitialized => "Allocator has not been initialized",
69 Self::InvalidOrder => "Invalid block order specified",
70 Self::InternalCorruption => "Internal allocator corruption detected",
71 }
72 }
73
74 #[inline]
79 #[must_use]
80 pub const fn to_kernel_error(self) -> KernelError {
81 match self {
82 Self::OutOfMemory | Self::AllocationTooLarge => KernelError::OutOfMemory,
83 Self::ZeroAllocation | Self::InvalidOrder => KernelError::InvalidArgument,
84 Self::UnalignedAddress | Self::AddressOutOfRange => KernelError::InvalidArgument,
85 Self::NotAllocated | Self::SizeMismatch => KernelError::InvalidArgument,
86 Self::NotInitialized => KernelError::NotPermitted,
87 Self::InternalCorruption => KernelError::InternalError,
88 }
89 }
90}
91
92impl fmt::Display for PhysMemError {
93 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94 write!(f, "{}", self.as_str())
95 }
96}
97
98impl From<PhysMemError> for KernelError {
99 #[inline]
100 fn from(err: PhysMemError) -> Self {
101 err.to_kernel_error()
102 }
103}
104
105#[cfg(feature = "std")]
106impl std::error::Error for PhysMemError {}
107
108#[cfg(test)]
109mod tests {
110 extern crate alloc;
111 use alloc::format;
112 use super::*;
113
114 #[test]
115 fn test_error_as_str() {
116 assert_eq!(PhysMemError::OutOfMemory.as_str(), "Out of physical memory");
117 assert_eq!(
118 PhysMemError::AllocationTooLarge.as_str(),
119 "Allocation size exceeds maximum block size"
120 );
121 assert_eq!(
122 PhysMemError::ZeroAllocation.as_str(),
123 "Cannot allocate zero pages"
124 );
125 assert_eq!(
126 PhysMemError::UnalignedAddress.as_str(),
127 "Address is not page-aligned"
128 );
129 }
130
131 #[test]
132 fn test_to_kernel_error() {
133 assert_eq!(
134 PhysMemError::OutOfMemory.to_kernel_error(),
135 KernelError::OutOfMemory
136 );
137 assert_eq!(
138 PhysMemError::AllocationTooLarge.to_kernel_error(),
139 KernelError::OutOfMemory
140 );
141 assert_eq!(
142 PhysMemError::ZeroAllocation.to_kernel_error(),
143 KernelError::InvalidArgument
144 );
145 assert_eq!(
146 PhysMemError::InternalCorruption.to_kernel_error(),
147 KernelError::InternalError
148 );
149 }
150
151 #[test]
152 fn test_into_kernel_error() {
153 let err: KernelError = PhysMemError::OutOfMemory.into();
154 assert_eq!(err, KernelError::OutOfMemory);
155 }
156
157 #[test]
158 fn test_display() {
159 assert_eq!(format!("{}", PhysMemError::OutOfMemory), "Out of physical memory");
160 }
161
162 #[test]
163 fn test_debug() {
164 assert_eq!(format!("{:?}", PhysMemError::OutOfMemory), "OutOfMemory");
165 }
166}