#[cfg(feature = "error_in_core")]
use core::error::Error;
#[cfg(all(not(feature = "error_in_core"), not(feature = "no_std")))]
use std::error::Error;
#[cfg(not(feature = "no_std"))]
use std::sync::MutexGuard;
#[cfg(not(feature = "no_std"))]
use std::sync::PoisonError;
use core::alloc::LayoutError;
use core::fmt::Debug;
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
use core::fmt::{Display, Formatter, Result as FmtResult};
use crate::range::ByteRange;
#[derive(Debug)]
pub enum LockingError {
Poisoned {
source: LockSource,
},
WouldBlock {
source: LockSource,
},
}
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
impl Display for LockingError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
LockingError::Poisoned { source } => write!(
f,
"Cannot acquire lock: {}",
match source {
LockSource::BaseAddress => {
"base address Mutex was poisoned"
}
LockSource::AllocationTracker => "AllocationTracker Mutex was poisoned",
LockSource::Reference =>
"reference concurrent mutable access exclusion flag Mutex was poisoned",
}
),
LockingError::WouldBlock { source } => write!(
f,
"Lock would block the current thread: {}",
match source {
LockSource::BaseAddress => "base address already borrowed",
LockSource::AllocationTracker => "AllocationTracker already borrowed",
LockSource::Reference => "reference already borrowed",
}
),
}
}
}
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
impl Error for LockingError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
#[cfg(not(feature = "no_std"))]
impl From<PoisonError<MutexGuard<'_, *mut u8>>> for LockingError {
fn from(_: PoisonError<MutexGuard<'_, *mut u8>>) -> Self {
LockingError::Poisoned {
source: LockSource::BaseAddress,
}
}
}
#[cfg(not(feature = "no_std"))]
impl From<PoisonError<MutexGuard<'_, crate::tracker::AllocationTracker>>> for LockingError {
fn from(_: PoisonError<MutexGuard<'_, crate::tracker::AllocationTracker>>) -> Self {
LockingError::Poisoned {
source: LockSource::AllocationTracker,
}
}
}
#[derive(Debug)]
pub struct RegionBorrowedError {
pub range: ByteRange,
}
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
impl Display for RegionBorrowedError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(
f,
"attempted to borrow already mutably borrowed memory region: {}",
self.range
)
}
}
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
impl Error for RegionBorrowedError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
None
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum ContiguousMemoryError {
NoStorageLeft,
AlreadyUsed,
NotContained,
DoubleFree,
Unshrinkable {
required_size: usize,
},
Lock(LockingError),
Layout(
LayoutError,
),
BorrowMut(RegionBorrowedError),
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum LockSource {
BaseAddress,
AllocationTracker,
Reference,
}
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
impl Display for ContiguousMemoryError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
ContiguousMemoryError::NoStorageLeft => {
write!(f, "Insufficient free storage available")
}
ContiguousMemoryError::NotContained => {
write!(f, "Attempted to mark a memory region that isn't contained")
}
ContiguousMemoryError::AlreadyUsed => write!(
f,
"Attempted to take a memory region that is already marked as occupied"
),
ContiguousMemoryError::DoubleFree => write!(
f,
"Attempted to free a memory region that is already marked as free"
),
ContiguousMemoryError::Unshrinkable {
required_size: min_required,
} => write!(
f,
"Cannot shrink memory regions; minimum required space: {} bytes",
min_required
),
ContiguousMemoryError::Lock(it) => write!(f, "Poison error: {}", it),
ContiguousMemoryError::Layout(it) => write!(f, "Layout error: {}", it),
ContiguousMemoryError::BorrowMut(it) => write!(f, "Borrow mutable error: {}", it),
}
}
}
#[cfg(any(not(feature = "no_std"), feature = "error_in_core"))]
impl Error for ContiguousMemoryError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
ContiguousMemoryError::Layout(it) => Some(it),
ContiguousMemoryError::Lock(it) => Some(it),
_ => None,
}
}
}
impl From<LockingError> for ContiguousMemoryError {
fn from(layout_err: LockingError) -> Self {
ContiguousMemoryError::Lock(layout_err)
}
}
impl From<LayoutError> for ContiguousMemoryError {
fn from(layout_err: LayoutError) -> Self {
ContiguousMemoryError::Layout(layout_err)
}
}