hv_guarded_borrow/
lib.rs

1//! Heavy Guarded-Borrow - traits for generalizing over guarded borrow operations
2//!
3//! Using these traits allows you to write code which generalizes over the type of "guard" that a
4//! type like `Mutex`, `RwLock`, `RefCell`, `AtomicRefCell`, etc. may return.
5
6#![feature(generic_associated_types)]
7#![cfg_attr(not(feature = "std"), no_std)]
8#![warn(missing_docs)]
9
10extern crate alloc;
11
12use alloc::{boxed::Box, rc::Rc, sync::Arc};
13use core::ops::{Deref, DerefMut};
14use core::{
15    cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut},
16    convert::Infallible,
17};
18
19#[cfg(feature = "hv-ecs")]
20mod hv_ecs;
21
22#[cfg(feature = "std")]
23mod std;
24
25/// Abstracts over non-blocking guarded immutable borrows (for example, `RefCell::try_borrow`.)
26pub trait NonBlockingGuardedBorrow<T: ?Sized> {
27    /// The guard type (for example, `std::cell::Ref<'a, T>`.)
28    type Guard<'a>: Deref<Target = T>
29    where
30        T: 'a,
31        Self: 'a;
32    /// The type returned in the case the value cannot be borrowed.
33    type BorrowError<'a>
34    where
35        T: 'a,
36        Self: 'a;
37
38    /// Attempt to perform the borrow.
39    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>>;
40}
41
42/// Abstracts over non-blocking guarded mutable borrows from behind immutable references
43/// (for example, `RefCell::try_borrow_mut`.)
44pub trait NonBlockingGuardedBorrowMut<T: ?Sized> {
45    /// The guard type (for example, `std::cell::RefMut<'a, T>`.)
46    type GuardMut<'a>: Deref<Target = T> + DerefMut
47    where
48        T: 'a,
49        Self: 'a;
50    /// The type returned in the case the value cannot be borrowed.
51    type BorrowMutError<'a>
52    where
53        T: 'a,
54        Self: 'a;
55
56    /// Attempt to perform the borrow.
57    fn try_nonblocking_guarded_borrow_mut(
58        &self,
59    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>>;
60}
61
62/// Abstracts over non-blocking guarded mutable borrows from behind mutable references
63/// (for example, `RefCell::get_mut`, or calling `.write()` on an `&mut Arc<RwLock<T>>`.)
64pub trait NonBlockingGuardedMutBorrowMut<T: ?Sized> {
65    /// The guard type (for example, `std::sync::RwLockWriteGuard<'a, T>`.)
66    type MutGuardMut<'a>: Deref<Target = T> + DerefMut
67    where
68        T: 'a,
69        Self: 'a;
70    /// The type returned in the case the value cannot be borrowed.
71    type MutBorrowMutError<'a>
72    where
73        T: 'a,
74        Self: 'a;
75
76    /// Attempt to perform the borrow.
77    fn try_nonblocking_guarded_mut_borrow_mut(
78        &mut self,
79    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>>;
80}
81
82impl<'a, T: ?Sized> NonBlockingGuardedBorrow<T> for &'a T {
83    type Guard<'b>
84    where
85        T: 'b,
86        Self: 'b,
87    = &'b T;
88    type BorrowError<'b>
89    where
90        T: 'b,
91        Self: 'b,
92    = Infallible;
93
94    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
95        Ok(self)
96    }
97}
98
99impl<'a, T: ?Sized> NonBlockingGuardedBorrowMut<T> for &'a T {
100    type GuardMut<'b>
101    where
102        T: 'b,
103        Self: 'b,
104    = &'b mut T;
105    type BorrowMutError<'b>
106    where
107        T: 'b,
108        Self: 'b,
109    = &'static str;
110
111    fn try_nonblocking_guarded_borrow_mut(
112        &self,
113    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
114        Err("cannot mutably borrow from behind a shared reference")
115    }
116}
117
118impl<'a, T: ?Sized> NonBlockingGuardedMutBorrowMut<T> for &'a T {
119    type MutGuardMut<'b>
120    where
121        T: 'b,
122        Self: 'b,
123    = &'b mut T;
124    type MutBorrowMutError<'b>
125    where
126        T: 'b,
127        Self: 'b,
128    = &'static str;
129
130    fn try_nonblocking_guarded_mut_borrow_mut(
131        &mut self,
132    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
133        Err("cannot mutably borrow from behind a shared reference")
134    }
135}
136
137impl<'a, T: ?Sized> NonBlockingGuardedBorrow<T> for &'a mut T {
138    type Guard<'b>
139    where
140        T: 'b,
141        Self: 'b,
142    = &'b T;
143    type BorrowError<'b>
144    where
145        T: 'b,
146        Self: 'b,
147    = Infallible;
148
149    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
150        Ok(self)
151    }
152}
153
154impl<'a, T: ?Sized> NonBlockingGuardedBorrowMut<T> for &'a mut T {
155    type GuardMut<'b>
156    where
157        T: 'b,
158        Self: 'b,
159    = &'b mut T;
160    type BorrowMutError<'b>
161    where
162        T: 'b,
163        Self: 'b,
164    = &'static str;
165
166    fn try_nonblocking_guarded_borrow_mut(
167        &self,
168    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
169        Err("cannot mutably borrow from behind a shared reference")
170    }
171}
172
173impl<'a, T: ?Sized> NonBlockingGuardedMutBorrowMut<T> for &'a mut T {
174    type MutGuardMut<'b>
175    where
176        T: 'b,
177        Self: 'b,
178    = &'b mut T;
179    type MutBorrowMutError<'b>
180    where
181        T: 'b,
182        Self: 'b,
183    = Infallible;
184
185    fn try_nonblocking_guarded_mut_borrow_mut(
186        &mut self,
187    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
188        Ok(self)
189    }
190}
191
192impl<T: ?Sized> NonBlockingGuardedBorrow<T> for RefCell<T> {
193    type Guard<'a>
194    where
195        T: 'a,
196    = Ref<'a, T>;
197    type BorrowError<'a>
198    where
199        T: 'a,
200    = BorrowError;
201
202    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
203        self.try_borrow()
204    }
205}
206
207impl<T: ?Sized> NonBlockingGuardedBorrowMut<T> for RefCell<T> {
208    type GuardMut<'a>
209    where
210        T: 'a,
211    = RefMut<'a, T>;
212    type BorrowMutError<'a>
213    where
214        T: 'a,
215    = BorrowMutError;
216
217    fn try_nonblocking_guarded_borrow_mut(
218        &self,
219    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
220        self.try_borrow_mut()
221    }
222}
223
224impl<T: ?Sized> NonBlockingGuardedMutBorrowMut<T> for RefCell<T> {
225    type MutGuardMut<'a>
226    where
227        T: 'a,
228    = &'a mut T;
229    type MutBorrowMutError<'a>
230    where
231        T: 'a,
232    = Infallible;
233
234    fn try_nonblocking_guarded_mut_borrow_mut(
235        &mut self,
236    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
237        Ok(self.get_mut())
238    }
239}
240
241impl<T: ?Sized, U: ?Sized> NonBlockingGuardedBorrow<U> for Rc<T>
242where
243    T: NonBlockingGuardedBorrow<U>,
244{
245    type Guard<'a>
246    where
247        U: 'a,
248        Self: 'a,
249    = T::Guard<'a>;
250    type BorrowError<'a>
251    where
252        U: 'a,
253        Self: 'a,
254    = T::BorrowError<'a>;
255
256    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
257        T::try_nonblocking_guarded_borrow(self)
258    }
259}
260
261impl<T: ?Sized, U: ?Sized> NonBlockingGuardedBorrowMut<U> for Rc<T>
262where
263    T: NonBlockingGuardedBorrowMut<U>,
264{
265    type GuardMut<'a>
266    where
267        U: 'a,
268        Self: 'a,
269    = T::GuardMut<'a>;
270    type BorrowMutError<'a>
271    where
272        U: 'a,
273        Self: 'a,
274    = T::BorrowMutError<'a>;
275
276    fn try_nonblocking_guarded_borrow_mut(
277        &self,
278    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
279        T::try_nonblocking_guarded_borrow_mut(self)
280    }
281}
282
283impl<T: ?Sized, U: ?Sized> NonBlockingGuardedMutBorrowMut<U> for Rc<T>
284where
285    T: NonBlockingGuardedBorrowMut<U>,
286{
287    type MutGuardMut<'a>
288    where
289        U: 'a,
290        Self: 'a,
291    = T::GuardMut<'a>;
292    type MutBorrowMutError<'a>
293    where
294        U: 'a,
295        Self: 'a,
296    = T::BorrowMutError<'a>;
297
298    fn try_nonblocking_guarded_mut_borrow_mut(
299        &mut self,
300    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
301        T::try_nonblocking_guarded_borrow_mut(self)
302    }
303}
304
305impl<T: ?Sized, U: ?Sized> NonBlockingGuardedBorrow<U> for Arc<T>
306where
307    T: NonBlockingGuardedBorrow<U>,
308{
309    type Guard<'a>
310    where
311        U: 'a,
312        Self: 'a,
313    = T::Guard<'a>;
314    type BorrowError<'a>
315    where
316        U: 'a,
317        Self: 'a,
318    = T::BorrowError<'a>;
319
320    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
321        T::try_nonblocking_guarded_borrow(self)
322    }
323}
324
325impl<T: ?Sized, U: ?Sized> NonBlockingGuardedBorrowMut<U> for Arc<T>
326where
327    T: NonBlockingGuardedBorrowMut<U>,
328{
329    type GuardMut<'a>
330    where
331        U: 'a,
332        Self: 'a,
333    = T::GuardMut<'a>;
334    type BorrowMutError<'a>
335    where
336        U: 'a,
337        Self: 'a,
338    = T::BorrowMutError<'a>;
339
340    fn try_nonblocking_guarded_borrow_mut(
341        &self,
342    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
343        T::try_nonblocking_guarded_borrow_mut(self)
344    }
345}
346
347impl<T: ?Sized, U: ?Sized> NonBlockingGuardedMutBorrowMut<U> for Arc<T>
348where
349    T: NonBlockingGuardedBorrowMut<U>,
350{
351    type MutGuardMut<'a>
352    where
353        U: 'a,
354        Self: 'a,
355    = T::GuardMut<'a>;
356    type MutBorrowMutError<'a>
357    where
358        U: 'a,
359        Self: 'a,
360    = T::BorrowMutError<'a>;
361
362    fn try_nonblocking_guarded_mut_borrow_mut(
363        &mut self,
364    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
365        T::try_nonblocking_guarded_borrow_mut(self)
366    }
367}
368
369impl<T: ?Sized, U: ?Sized> NonBlockingGuardedBorrow<U> for Box<T>
370where
371    T: NonBlockingGuardedBorrow<U>,
372{
373    type Guard<'a>
374    where
375        U: 'a,
376        Self: 'a,
377    = T::Guard<'a>;
378    type BorrowError<'a>
379    where
380        U: 'a,
381        Self: 'a,
382    = T::BorrowError<'a>;
383
384    fn try_nonblocking_guarded_borrow(&self) -> Result<Self::Guard<'_>, Self::BorrowError<'_>> {
385        T::try_nonblocking_guarded_borrow(self)
386    }
387}
388
389impl<T: ?Sized, U: ?Sized> NonBlockingGuardedBorrowMut<U> for Box<T>
390where
391    T: NonBlockingGuardedBorrowMut<U>,
392{
393    type GuardMut<'a>
394    where
395        U: 'a,
396        Self: 'a,
397    = T::GuardMut<'a>;
398    type BorrowMutError<'a>
399    where
400        U: 'a,
401        Self: 'a,
402    = T::BorrowMutError<'a>;
403
404    fn try_nonblocking_guarded_borrow_mut(
405        &self,
406    ) -> Result<Self::GuardMut<'_>, Self::BorrowMutError<'_>> {
407        T::try_nonblocking_guarded_borrow_mut(self)
408    }
409}
410
411impl<T: ?Sized, U: ?Sized> NonBlockingGuardedMutBorrowMut<U> for Box<T>
412where
413    T: NonBlockingGuardedMutBorrowMut<U>,
414{
415    type MutGuardMut<'a>
416    where
417        U: 'a,
418        Self: 'a,
419    = T::MutGuardMut<'a>;
420    type MutBorrowMutError<'a>
421    where
422        U: 'a,
423        Self: 'a,
424    = T::MutBorrowMutError<'a>;
425
426    fn try_nonblocking_guarded_mut_borrow_mut(
427        &mut self,
428    ) -> Result<Self::MutGuardMut<'_>, Self::MutBorrowMutError<'_>> {
429        T::try_nonblocking_guarded_mut_borrow_mut(self)
430    }
431}