use std::fmt::{Debug, Display}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::sync::atomic::Ordering::Relaxed; use crate::Keyable; use super::{PoisonFlag, PoisonGuard, PoisonRef}; impl<'a, Guard> PoisonRef<'a, Guard> { // This is used so that we don't keep accidentally adding the flag reference pub(super) const fn new(flag: &'a PoisonFlag, guard: Guard) -> Self { Self { guard, #[cfg(panic = "unwind")] flag, _phantom: PhantomData, } } } impl<'flag, Guard> Drop for PoisonRef<'flag, Guard> { fn drop(&mut self) { #[cfg(panic = "unwind")] if std::thread::panicking() { self.flag.0.store(true, Relaxed); } } } impl<'flag, Guard: Debug> Debug for PoisonRef<'flag, Guard> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Debug::fmt(&**self, f) } } impl<'flag, Guard: Display> Display for PoisonRef<'flag, Guard> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&**self, f) } } impl<'flag, Guard> Deref for PoisonRef<'flag, Guard> { type Target = Guard; fn deref(&self) -> &Self::Target { &self.guard } } impl<'flag, Guard> DerefMut for PoisonRef<'flag, Guard> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.guard } } impl<'flag, Guard> AsRef for PoisonRef<'flag, Guard> { fn as_ref(&self) -> &Guard { &self.guard } } impl<'flag, Guard> AsMut for PoisonRef<'flag, Guard> { fn as_mut(&mut self) -> &mut Guard { &mut self.guard } } impl<'flag, 'key, Guard: Debug, Key: Keyable> Debug for PoisonGuard<'flag, 'key, Guard, Key> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Debug::fmt(&self.guard, f) } } impl<'flag, 'key, Guard: Display, Key: Keyable> Display for PoisonGuard<'flag, 'key, Guard, Key> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Display::fmt(&self.guard, f) } } impl<'flag, 'key, T, Guard: Deref, Key: Keyable> Deref for PoisonGuard<'flag, 'key, Guard, Key> { type Target = T; fn deref(&self) -> &Self::Target { #[allow(clippy::explicit_auto_deref)] // fixing this results in a compiler error &*self.guard.guard } } impl<'flag, 'key, T, Guard: DerefMut, Key: Keyable> DerefMut for PoisonGuard<'flag, 'key, Guard, Key> { fn deref_mut(&mut self) -> &mut Self::Target { #[allow(clippy::explicit_auto_deref)] // fixing this results in a compiler error &mut *self.guard.guard } } impl<'flag, 'key, Guard, Key: Keyable> AsRef for PoisonGuard<'flag, 'key, Guard, Key> { fn as_ref(&self) -> &Guard { &self.guard.guard } } impl<'flag, 'key, Guard, Key: Keyable> AsMut for PoisonGuard<'flag, 'key, Guard, Key> { fn as_mut(&mut self) -> &mut Guard { &mut self.guard.guard } }