generic_container/impls/
arc_checked_mutex.rs1use alloc::sync::Arc;
2
3use thread_checked_lock::{
4 HandlePoisonResult as _, LockError, ThreadCheckedMutex, ThreadCheckedMutexGuard,
5};
6
7use crate::container_traits::{
8 FragileTryContainer, FragileTryMutContainer, TryContainer, TryMutContainer,
9};
10
11
12#[derive(Debug, Clone, Copy)]
15pub enum ErasedLockError {
16 Poisoned,
18 LockedByCurrentThread,
20}
21
22impl ErasedLockError {
23 #[inline]
30 #[must_use]
31 pub fn panic_if_poison(self) -> Self {
32 match self {
33 #[expect(
34 clippy::panic,
35 reason = "library users will frequently want to panic on poison",
36 )]
37 Self::Poisoned => panic!("ErasedLockError was poison"),
38 Self::LockedByCurrentThread => Self::LockedByCurrentThread,
39 }
40 }
41}
42
43impl<T> From<LockError<T>> for ErasedLockError {
44 #[inline]
45 fn from(value: LockError<T>) -> Self {
46 match value {
47 LockError::Poisoned(_) => Self::Poisoned,
48 LockError::LockedByCurrentThread => Self::LockedByCurrentThread,
49 }
50 }
51}
52
53impl<T: ?Sized> FragileTryContainer<T> for Arc<ThreadCheckedMutex<T>> {
54 type Ref<'a> = ThreadCheckedMutexGuard<'a, T> where T: 'a;
55 type RefError = ErasedLockError;
56
57 #[inline]
58 fn new_container(t: T) -> Self where T: Sized {
59 Self::new(ThreadCheckedMutex::new(t))
60 }
61
62 #[inline]
67 fn into_inner(self) -> Option<T> where T: Sized {
68 let result = Self::into_inner(self)?
69 .into_inner()
70 .ignore_poison();
71
72 match result {
74 Ok(t) => Some(t),
75 #[expect(unreachable_code, reason = "yeah, that's the point")]
76 Err(poisonless_poison) => match poisonless_poison.poison.into_inner() {},
77 }
78 }
79
80 #[inline]
88 fn try_get_ref(&self) -> Result<Self::Ref<'_>, Self::RefError> {
89 self.lock().map_err(Into::into)
90 }
91}
92
93impl<T: ?Sized> TryContainer<T> for Arc<ThreadCheckedMutex<T>> {}
94
95impl<T: ?Sized> FragileTryMutContainer<T> for Arc<ThreadCheckedMutex<T>> {
96 type RefMut<'a> = ThreadCheckedMutexGuard<'a, T> where T: 'a;
97 type RefMutError = ErasedLockError;
98
99 #[inline]
107 fn try_get_mut(&mut self) -> Result<Self::RefMut<'_>, Self::RefMutError> {
108 self.lock().map_err(Into::into)
109 }
110}
111
112impl<T: ?Sized> TryMutContainer<T> for Arc<ThreadCheckedMutex<T>> {}