memvec/
memory.rs

1use crate::MemVec;
2
3#[allow(clippy::len_without_is_empty)]
4pub trait Memory
5where
6    Self: core::ops::Deref<Target = [u8]> + core::ops::DerefMut<Target = [u8]>,
7{
8    type Error: core::fmt::Debug;
9
10    /// Returns a raw pointer to the memory's buffer.
11    fn as_ptr(&self) -> *const u8;
12
13    /// Returns an unsafe mutable pointer to the memory's buffer.
14    fn as_mut_ptr(&mut self) -> *mut u8;
15
16    /// Returns the number of elements in the memory, also referred to as its 'length'.
17    fn len(&self) -> usize;
18
19    /// Returns a mutable reference to the length field for direct manipulation.
20    /// This method is used when the length of Vec elements changes, such as with set_len.
21    fn len_mut(&mut self) -> &mut usize;
22
23    /// Reserves capacity for at least `capacity` bytes of data.
24    ///
25    /// The allocator may reserve more space to speculatively avoid frequent allocations.
26    /// After calling `reserve`, capacity will be greater than or equal to `capacity`.
27    /// Does nothing if capacity is already sufficient.
28    fn reserve(&mut self, capacity: usize) -> Result<(), Self::Error>;
29
30    /// Shrinks the capacity of the memory as much as possible.
31    ///
32    /// It will drop down as close as possible to the given capacity, but the allocator
33    /// may still inform the memory that there is space for a few more elements.
34    fn shrink_to(&mut self, capacity: usize) -> Result<(), Self::Error>;
35
36    /// Create a MemVec object with memory.
37    /// # Safety
38    /// The memory must represent valid len and bytes representations of T.
39    unsafe fn try_into_memvec<'a, T: Copy>(
40        self,
41    ) -> Result<MemVec<'a, T, Self>, (Self, MemoryLayoutError)>
42    where
43        Self: Sized,
44    {
45        MemVec::try_from_memory(self)
46    }
47}
48
49/// Errors that can occur when converting memory into a `MemVec`.
50///
51/// These errors indicate fundamental incompatibilities between the memory layout
52/// and the target type `T`. When these errors occur, the original memory is returned
53/// unchanged, allowing for recovery or alternative handling.
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum MemoryLayoutError {
56    /// The memory is not properly aligned for the target type `T`.
57    ///
58    /// This occurs when the memory address is not aligned to the alignment
59    /// requirements of type `T`. Common causes include memory-mapped files
60    /// that don't start on proper boundaries or custom memory implementations
61    /// with incorrect alignment.
62    MisalignedMemory,
63
64    /// The logical length stored in memory exceeds the available capacity.
65    ///
66    /// This occurs when the memory claims to contain more elements than can
67    /// physically fit in the allocated space. Common causes include corrupted
68    /// metadata in file-backed storage, version incompatibility, or bugs in
69    /// length management.
70    CapacityExceeded,
71}
72
73impl core::fmt::Display for MemoryLayoutError {
74    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
75        match self {
76            MemoryLayoutError::MisalignedMemory => {
77                write!(f, "memory is not properly aligned for the target type")
78            }
79            MemoryLayoutError::CapacityExceeded => {
80                write!(f, "logical length exceeds available memory capacity")
81            }
82        }
83    }
84}
85
86impl core::error::Error for MemoryLayoutError {}