generational_box/
error.rs

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