ps-alloc 0.1.0-9

a reasonably safe allocator
Documentation
use std::alloc::LayoutError;

use thiserror::Error;

/// Errors returned by [`crate::alloc`].
#[derive(Debug, Error, PartialEq, Eq, Clone)]
pub enum AllocationError {
    /// The allocation size computation overflowed.
    #[error("an arithmetic error occurred")]
    ArithmeticError,
    /// The requested size does not form a valid [`Layout`](std::alloc::Layout).
    #[error(transparent)]
    LayoutError(#[from] LayoutError),
    /// The underlying allocator returned a null pointer.
    #[error("process ran out of memory")]
    OutOfMemory,
}

/// Errors returned by [`crate::free`].
#[derive(Debug, Error, PartialEq, Eq, Clone)]
pub enum DeallocationError {
    /// The header matches neither marker: either memory corruption occurred, or the
    /// pointer was not produced by this crate.
    #[error("this allocation's marker is corrupted: either memory corruption occurred, or a pointer not allocated by this crate's alloc was passed to realloc or free")]
    CorruptedMarker,
    /// The allocation was already freed.
    #[error("this memory was already freed")]
    DoubleFree,
    /// The pointer is not properly aligned.
    #[error("the pointer provided was not properly aligned")]
    ImproperAlignment,
    /// The size stored in the header does not form a valid layout, which signals memory
    /// corruption.
    #[error(transparent)]
    LayoutError(#[from] LayoutError),
    /// The pointer is null.
    #[error("tried to free a null pointer")]
    NullPtr,
}

/// The ways a user pointer can fail validation, mapped into each public error enum.
pub(crate) enum ValidationError {
    ImproperAlignment,
    MarkerFree,
    MarkerCorrupted,
}

impl From<ValidationError> for DeallocationError {
    fn from(error: ValidationError) -> Self {
        match error {
            ValidationError::ImproperAlignment => Self::ImproperAlignment,
            ValidationError::MarkerFree => Self::DoubleFree,
            ValidationError::MarkerCorrupted => Self::CorruptedMarker,
        }
    }
}

impl From<ValidationError> for ReallocationError {
    fn from(error: ValidationError) -> Self {
        match error {
            ValidationError::ImproperAlignment => Self::ImproperAlignment,
            ValidationError::MarkerFree => Self::MarkerFree,
            ValidationError::MarkerCorrupted => Self::MarkerCorrupted,
        }
    }
}

/// Errors returned by [`crate::realloc`].
#[derive(Debug, Error, PartialEq, Eq, Clone)]
pub enum ReallocationError {
    /// Computing the new size or allocating the new memory failed.
    #[error(transparent)]
    AllocationError(#[from] AllocationError),
    /// Freeing failed; only `LayoutError` is reachable, and it signals memory corruption.
    #[error(transparent)]
    DeallocationError(#[from] DeallocationError),
    /// The pointer is not properly aligned.
    #[error("the pointer provided was not properly aligned")]
    ImproperAlignment,
    /// The pointer points to already freed memory.
    #[error("the pointer provided points to already freed memory")]
    MarkerFree,
    /// The header matches neither marker: either memory corruption occurred, or the
    /// pointer was not produced by this crate.
    #[error("the pointer provided has a corrupted marker; was it allocated by this crate?")]
    MarkerCorrupted,
    /// The old pointer remains valid and must still be freed by the caller.
    #[error("the new allocation failed, but your old pointer remains valid")]
    NewAllocationFailed,
}