or_poisoned/
lib.rs

1//! Provides a simple trait that unwraps the locks provide by [`std::sync::RwLock`].
2//!
3//! In every case, this is the same as calling `.expect("lock poisoned")`. However, it
4//! does not use `.unwrap()` or `.expect()`, which makes it easier to distinguish from
5//! other forms of unwrapping when reading code.
6//!
7//! ```rust
8//! use or_poisoned::OrPoisoned;
9//! use std::sync::RwLock;
10//!
11//! let lock = RwLock::new(String::from("Hello!"));
12//!
13//! let read = lock.read().or_poisoned();
14//! // this is identical to
15//! let read = lock.read().unwrap();
16//! ```
17
18#![forbid(unsafe_code)]
19#![deny(missing_docs)]
20
21use std::sync::{
22    LockResult, MutexGuard, PoisonError, RwLockReadGuard, RwLockWriteGuard,
23};
24
25/// Unwraps a lock.
26pub trait OrPoisoned {
27    /// The inner guard type.
28    type Inner;
29
30    /// Unwraps the lock.
31    ///
32    /// ## Panics
33    ///
34    /// Will panic if the lock is poisoned.
35    fn or_poisoned(self) -> Self::Inner;
36}
37
38impl<'a, T> OrPoisoned
39    for Result<RwLockReadGuard<'a, T>, PoisonError<RwLockReadGuard<'a, T>>>
40{
41    type Inner = RwLockReadGuard<'a, T>;
42
43    fn or_poisoned(self) -> Self::Inner {
44        self.expect("lock poisoned")
45    }
46}
47
48impl<'a, T> OrPoisoned
49    for Result<RwLockWriteGuard<'a, T>, PoisonError<RwLockWriteGuard<'a, T>>>
50{
51    type Inner = RwLockWriteGuard<'a, T>;
52
53    fn or_poisoned(self) -> Self::Inner {
54        self.expect("lock poisoned")
55    }
56}
57
58impl<'a, T> OrPoisoned for LockResult<MutexGuard<'a, T>> {
59    type Inner = MutexGuard<'a, T>;
60
61    fn or_poisoned(self) -> Self::Inner {
62        self.expect("lock poisoned")
63    }
64}