generational_box/
error.rs

1//! Generational box errors
2#![allow(clippy::uninlined_format_args, reason = "causes compile error")]
3
4use std::error::Error;
5use std::fmt::Debug;
6use std::fmt::Display;
7
8use crate::GenerationalLocation;
9
10/// A result that can be returned from a borrow operation.
11pub type BorrowResult<T = ()> = std::result::Result<T, BorrowError>;
12
13/// A result that can be returned from a borrow mut operation.
14pub type BorrowMutResult<T = ()> = std::result::Result<T, BorrowMutError>;
15
16#[derive(Debug, Clone, PartialEq)]
17/// An error that can occur when trying to borrow a value.
18pub enum BorrowError {
19    /// The value was dropped.
20    Dropped(ValueDroppedError),
21    /// The value was already borrowed mutably.
22    AlreadyBorrowedMut(AlreadyBorrowedMutError),
23}
24
25impl Display for BorrowError {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            BorrowError::Dropped(error) => Display::fmt(error, f),
29            BorrowError::AlreadyBorrowedMut(error) => Display::fmt(error, f),
30        }
31    }
32}
33
34impl Error for BorrowError {}
35
36#[derive(Debug, Clone, PartialEq)]
37/// An error that can occur when trying to borrow a value mutably.
38pub enum BorrowMutError {
39    /// The value was dropped.
40    Dropped(ValueDroppedError),
41    /// The value was already borrowed.
42    AlreadyBorrowed(AlreadyBorrowedError),
43    /// The value was already borrowed mutably.
44    AlreadyBorrowedMut(AlreadyBorrowedMutError),
45}
46
47impl Display for BorrowMutError {
48    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49        match self {
50            BorrowMutError::Dropped(error) => Display::fmt(error, f),
51            BorrowMutError::AlreadyBorrowedMut(error) => Display::fmt(error, f),
52            BorrowMutError::AlreadyBorrowed(error) => Display::fmt(error, f),
53        }
54    }
55}
56
57impl Error for BorrowMutError {}
58
59impl From<BorrowError> for BorrowMutError {
60    fn from(error: BorrowError) -> Self {
61        match error {
62            BorrowError::Dropped(error) => BorrowMutError::Dropped(error),
63            BorrowError::AlreadyBorrowedMut(error) => BorrowMutError::AlreadyBorrowedMut(error),
64        }
65    }
66}
67
68/// An error that can occur when trying to use a value that has been dropped.
69#[derive(Debug, Copy, Clone, PartialEq)]
70pub struct ValueDroppedError {
71    #[cfg(any(debug_assertions, feature = "debug_ownership"))]
72    pub(crate) created_at: &'static std::panic::Location<'static>,
73}
74
75impl ValueDroppedError {
76    /// Create a new `ValueDroppedError`.
77    #[allow(unused)]
78    pub fn new(created_at: &'static std::panic::Location<'static>) -> Self {
79        Self {
80            #[cfg(any(debug_assertions, feature = "debug_ownership"))]
81            created_at,
82        }
83    }
84
85    /// Create a new `ValueDroppedError` for a [`GenerationalLocation`].
86    #[allow(unused)]
87    pub(crate) fn new_for_location(location: GenerationalLocation) -> Self {
88        Self {
89            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
90            created_at: location.created_at,
91        }
92    }
93}
94
95impl Display for ValueDroppedError {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        f.write_str("Failed to borrow because the value was dropped.")?;
98        #[cfg(any(debug_assertions, feature = "debug_ownership"))]
99        f.write_fmt(format_args!("created_at: {}", self.created_at))?;
100        Ok(())
101    }
102}
103
104impl std::error::Error for ValueDroppedError {}
105
106/// An error that can occur when trying to borrow a value that has already been borrowed mutably.
107#[derive(Debug, Copy, Clone, PartialEq)]
108pub struct AlreadyBorrowedMutError {
109    #[cfg(any(debug_assertions, feature = "debug_borrows"))]
110    pub(crate) borrowed_mut_at: &'static std::panic::Location<'static>,
111}
112
113impl AlreadyBorrowedMutError {
114    /// Create a new `AlreadyBorrowedMutError`.
115    #[allow(unused)]
116    pub fn new(borrowed_mut_at: &'static std::panic::Location<'static>) -> Self {
117        Self {
118            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
119            borrowed_mut_at,
120        }
121    }
122}
123
124impl Display for AlreadyBorrowedMutError {
125    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126        f.write_str("Failed to borrow because the value was already borrowed mutably.")?;
127        #[cfg(any(debug_assertions, feature = "debug_borrows"))]
128        f.write_fmt(format_args!("borrowed_mut_at: {}", self.borrowed_mut_at))?;
129        Ok(())
130    }
131}
132
133impl std::error::Error for AlreadyBorrowedMutError {}
134
135/// An error that can occur when trying to borrow a value mutably that has already been borrowed immutably.
136#[derive(Debug, Clone, PartialEq)]
137pub struct AlreadyBorrowedError {
138    #[cfg(any(debug_assertions, feature = "debug_borrows"))]
139    pub(crate) borrowed_at: Vec<&'static std::panic::Location<'static>>,
140}
141
142impl AlreadyBorrowedError {
143    /// Create a new `AlreadyBorrowedError`.
144    #[allow(unused)]
145    pub fn new(borrowed_at: Vec<&'static std::panic::Location<'static>>) -> Self {
146        Self {
147            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
148            borrowed_at,
149        }
150    }
151}
152
153impl Display for AlreadyBorrowedError {
154    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155        f.write_str("Failed to borrow mutably because the value was already borrowed immutably.")?;
156        #[cfg(any(debug_assertions, feature = "debug_borrows"))]
157        f.write_str("borrowed_at:")?;
158        #[cfg(any(debug_assertions, feature = "debug_borrows"))]
159        for location in self.borrowed_at.iter() {
160            f.write_fmt(format_args!("\t{}", location))?;
161        }
162        Ok(())
163    }
164}
165
166impl std::error::Error for AlreadyBorrowedError {}