Skip to main content

arena_alligator/
error.rs

1use core::fmt;
2
3/// Allocation failed.
4#[derive(Debug, Clone, PartialEq, Eq)]
5#[non_exhaustive]
6pub enum AllocError {
7    /// The arena is temporarily exhausted: every slot or block of the needed
8    /// size is in use. A later attempt may succeed once buffers are freed.
9    ArenaFull,
10    /// The request is larger than the arena can ever satisfy, regardless of
11    /// free space. Retrying will never succeed.
12    RequestTooLarge,
13}
14
15impl fmt::Display for AllocError {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        match self {
18            AllocError::ArenaFull => write!(f, "arena is full"),
19            AllocError::RequestTooLarge => write!(f, "request exceeds total arena capacity"),
20        }
21    }
22}
23
24impl core::error::Error for AllocError {}
25
26/// Builder configuration error.
27#[derive(Debug, Clone, PartialEq, Eq)]
28#[non_exhaustive]
29pub enum BuildError {
30    /// `slot_count * aligned_capacity` overflows `usize`.
31    SizeOverflow,
32    /// Alignment is not a power of 2.
33    InvalidAlignment,
34    /// Buddy arena geometry is invalid.
35    InvalidGeometry,
36    /// Requested slot size exceeds backing memory length.
37    SlotSizeExceedsBacking,
38    /// No usable slots or blocks fit in the provided backing memory.
39    ZeroUsableSlots,
40    /// Null pointer provided to `from_raw`.
41    NullPointer,
42}
43
44impl fmt::Display for BuildError {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match self {
47            BuildError::SizeOverflow => write!(f, "total arena size overflows usize"),
48            BuildError::InvalidAlignment => write!(f, "alignment must be a power of 2"),
49            BuildError::InvalidGeometry => {
50                write!(
51                    f,
52                    "buddy arena geometry must be a power-of-two multiple of min block size"
53                )
54            }
55            BuildError::SlotSizeExceedsBacking => {
56                write!(f, "requested slot size exceeds backing memory length")
57            }
58            BuildError::ZeroUsableSlots => {
59                write!(f, "no usable slots fit in the provided backing memory")
60            }
61            BuildError::NullPointer => write!(f, "null pointer provided to from_raw"),
62        }
63    }
64}
65
66impl core::error::Error for BuildError {}
67
68/// Buffer capacity exceeded.
69#[derive(Debug, Clone, PartialEq, Eq)]
70#[non_exhaustive]
71pub struct BufferFullError {
72    /// Bytes remaining in the buffer.
73    pub remaining: usize,
74    /// Bytes that were requested.
75    pub requested: usize,
76}
77
78impl fmt::Display for BufferFullError {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        write!(
81            f,
82            "buffer full: {} bytes requested, {} bytes remaining",
83            self.requested, self.remaining,
84        )
85    }
86}
87
88impl core::error::Error for BufferFullError {}
89
90#[cfg(test)]
91mod tests {
92    use alloc::boxed::Box;
93    use alloc::string::ToString;
94
95    use super::*;
96
97    #[test]
98    fn alloc_error_display() {
99        let err = AllocError::ArenaFull;
100        assert_eq!(err.to_string(), "arena is full");
101    }
102
103    #[test]
104    fn request_too_large_display() {
105        assert_eq!(
106            AllocError::RequestTooLarge.to_string(),
107            "request exceeds total arena capacity"
108        );
109    }
110
111    #[test]
112    fn alloc_error_is_std_error() {
113        let err: Box<dyn core::error::Error> = Box::new(AllocError::ArenaFull);
114        assert_eq!(err.to_string(), "arena is full");
115    }
116
117    #[test]
118    fn build_error_display_variants() {
119        assert_eq!(
120            BuildError::SizeOverflow.to_string(),
121            "total arena size overflows usize"
122        );
123        assert_eq!(
124            BuildError::InvalidAlignment.to_string(),
125            "alignment must be a power of 2"
126        );
127        assert_eq!(
128            BuildError::InvalidGeometry.to_string(),
129            "buddy arena geometry must be a power-of-two multiple of min block size"
130        );
131        assert_eq!(
132            BuildError::SlotSizeExceedsBacking.to_string(),
133            "requested slot size exceeds backing memory length"
134        );
135        assert_eq!(
136            BuildError::ZeroUsableSlots.to_string(),
137            "no usable slots fit in the provided backing memory"
138        );
139        assert_eq!(
140            BuildError::NullPointer.to_string(),
141            "null pointer provided to from_raw"
142        );
143    }
144
145    #[test]
146    fn build_error_is_std_error() {
147        let err: Box<dyn core::error::Error> = Box::new(BuildError::SizeOverflow);
148        assert!(err.to_string().contains("overflows"));
149    }
150
151    #[test]
152    fn buffer_full_error_display() {
153        let err = BufferFullError {
154            remaining: 10,
155            requested: 50,
156        };
157        assert_eq!(
158            err.to_string(),
159            "buffer full: 50 bytes requested, 10 bytes remaining"
160        );
161    }
162}