1use {
8 crate::utils::cold_path::cold_path,
9 std::{
10 cell::{Cell, Ref, RefCell, RefMut},
11 fmt::{Debug, Display, Formatter},
12 mem::{self},
13 ops::{Deref, DerefMut},
14 },
15 thiserror::Error,
16};
17
18#[cfg(test)]
19mod tests;
20
21pub(crate) struct HandlerHolder<T: ?Sized> {
22 handler: RefCell<Option<Box<T>>>,
23 needs_update: Cell<bool>,
24 new: Cell<Option<Option<Box<T>>>>,
25}
26
27trait HandlerHolderDyn {
28 fn update(&self);
29}
30
31#[derive(Clone)]
32struct HandlerHolderUpdate<'a> {
33 needs_update: &'a Cell<bool>,
34 holder: &'a dyn HandlerHolderDyn,
35}
36
37pub struct HandlerMut<'a, U: ?Sized> {
39 handler: RefMut<'a, U>,
40 update: HandlerHolderUpdate<'a>,
41}
42
43pub struct HandlerRef<'a, U: ?Sized> {
45 handler: Ref<'a, U>,
46 update: HandlerHolderUpdate<'a>,
47}
48
49#[derive(Debug, Error)]
51pub enum HandlerAccessError {
52 #[error("the handler is already borrowed")]
54 AlreadyBorrowed,
55 #[error("the object has no handler")]
57 NoHandler,
58 #[error("the handler has a different type")]
60 InvalidType,
61}
62
63impl<T: ?Sized> HandlerHolderDyn for HandlerHolder<T> {
64 fn update(&self) {
65 let _old;
66 if let Ok(mut handler) = self.handler.try_borrow_mut() {
67 if let Some(new) = self.new.take() {
68 _old = mem::replace(&mut *handler, new);
69 }
70 self.needs_update.set(false);
71 }
72 }
73}
74
75impl<T: ?Sized> Default for HandlerHolder<T> {
76 fn default() -> Self {
77 Self {
78 handler: Default::default(),
79 needs_update: Default::default(),
80 new: Default::default(),
81 }
82 }
83}
84
85impl<T: ?Sized> HandlerHolder<T> {
86 #[inline]
87 fn update(&self) -> HandlerHolderUpdate<'_> {
88 HandlerHolderUpdate {
89 needs_update: &self.needs_update,
90 holder: self,
91 }
92 }
93
94 #[inline]
95 pub(crate) fn borrow_mut(&self) -> HandlerMut<'_, Option<Box<T>>> {
96 HandlerMut {
97 handler: self.handler.borrow_mut(),
98 update: self.update(),
99 }
100 }
101
102 #[inline]
103 pub(crate) fn try_borrow(&self) -> Option<HandlerRef<'_, Option<Box<T>>>> {
104 Some(HandlerRef {
105 handler: self.handler.try_borrow().ok()?,
106 update: self.update(),
107 })
108 }
109
110 #[inline]
111 pub(crate) fn try_borrow_mut(&self) -> Option<HandlerMut<'_, Option<Box<T>>>> {
112 Some(HandlerMut {
113 handler: self.handler.try_borrow_mut().ok()?,
114 update: self.update(),
115 })
116 }
117
118 pub(crate) fn set(&self, handler: Option<Box<T>>) {
119 let _prev;
120 if let Ok(mut cell) = self.handler.try_borrow_mut() {
121 _prev = mem::replace(&mut *cell, handler);
122 } else {
123 cold_path();
124 self.new.set(Some(handler));
125 self.needs_update.set(true);
126 }
127 }
128}
129
130impl<T: ?Sized> Deref for HandlerRef<'_, T> {
131 type Target = T;
132
133 #[inline]
134 fn deref(&self) -> &Self::Target {
135 &self.handler
136 }
137}
138
139impl<T: ?Sized> Deref for HandlerMut<'_, T> {
140 type Target = T;
141
142 #[inline]
143 fn deref(&self) -> &Self::Target {
144 &self.handler
145 }
146}
147
148impl<T: ?Sized> DerefMut for HandlerMut<'_, T> {
149 #[inline]
150 fn deref_mut(&mut self) -> &mut Self::Target {
151 &mut self.handler
152 }
153}
154
155impl<T: ?Sized> HandlerRef<'_, T> {
156 #[expect(clippy::should_implement_trait)]
160 pub fn clone(orig: &Self) -> Self {
161 Self {
162 handler: Ref::clone(&orig.handler),
163 update: orig.update.clone(),
164 }
165 }
166}
167
168impl<'a, T: ?Sized> HandlerRef<'a, T> {
169 #[inline]
175 pub fn map<U: ?Sized, F>(orig: Self, f: F) -> HandlerRef<'a, U>
176 where
177 F: FnOnce(&T) -> &U,
178 {
179 HandlerRef {
180 handler: Ref::map(orig.handler, f),
181 update: orig.update,
182 }
183 }
184}
185
186impl<'a, T: ?Sized> HandlerMut<'a, T> {
187 #[inline]
193 pub fn map<U: ?Sized, F>(orig: Self, f: F) -> HandlerMut<'a, U>
194 where
195 F: FnOnce(&mut T) -> &mut U,
196 {
197 HandlerMut {
198 handler: RefMut::map(orig.handler, f),
199 update: orig.update,
200 }
201 }
202}
203
204impl Drop for HandlerHolderUpdate<'_> {
205 #[inline]
206 fn drop(&mut self) {
207 if self.needs_update.get() {
208 cold_path();
209 self.holder.update();
210 }
211 }
212}
213
214impl<T: ?Sized> Debug for HandlerRef<'_, T>
215where
216 T: Debug,
217{
218 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
219 self.handler.fmt(f)
220 }
221}
222
223impl<T: ?Sized> Debug for HandlerMut<'_, T>
224where
225 T: Debug,
226{
227 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
228 self.handler.fmt(f)
229 }
230}
231
232impl<T: ?Sized> Display for HandlerRef<'_, T>
233where
234 T: Display,
235{
236 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
237 self.handler.fmt(f)
238 }
239}
240
241impl<T: ?Sized> Display for HandlerMut<'_, T>
242where
243 T: Display,
244{
245 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
246 self.handler.fmt(f)
247 }
248}