From 2376ccee97c99d5c47c09fcf308a97aaf785a29e Mon Sep 17 00:00:00 2001 From: Botahamec Date: Thu, 26 Sep 2024 22:58:13 -0400 Subject: Better into_inner and get_mut implementations --- src/poisonable/poisonable.rs | 66 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) (limited to 'src/poisonable') diff --git a/src/poisonable/poisonable.rs b/src/poisonable/poisonable.rs index ff43ff8..e1c4caa 100644 --- a/src/poisonable/poisonable.rs +++ b/src/poisonable/poisonable.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use std::panic::{RefUnwindSafe, UnwindSafe}; -use crate::lockable::{Lockable, RawLock}; +use crate::lockable::{Lockable, LockableAsMut, LockableIntoInner, RawLock}; use crate::Keyable; use super::{ @@ -282,9 +282,9 @@ impl Poisonable { /// use happylock::{Mutex, Poisonable}; /// /// let mutex = Poisonable::new(Mutex::new(0)); - /// assert_eq!(mutex.into_inner().unwrap().into_inner(), 0); + /// assert_eq!(mutex.inner_lock().unwrap().into_inner(), 0); /// ``` - pub fn into_inner(self) -> PoisonResult { + pub fn inner_lock(self) -> PoisonResult { if self.is_poisoned() { Err(PoisonError::new(self.inner)) } else { @@ -294,6 +294,58 @@ impl Poisonable { /// Returns a mutable reference to the underlying lock. /// + /// # Errors + /// + /// If another user of this lock panicked while holding the lock, then + /// this call will return an error instead. + /// + /// # Examples + /// + /// ``` + /// use happylock::{Mutex, Poisonable, ThreadKey}; + /// + /// let key = ThreadKey::get().unwrap(); + /// let mut mutex = Poisonable::new(Mutex::new(0)); + /// *mutex.lock_mut().unwrap().as_mut() = 10; + /// assert_eq!(*mutex.lock(key).unwrap(), 10); + /// ``` + pub fn lock_mut(&mut self) -> PoisonResult<&mut L> { + if self.is_poisoned() { + Err(PoisonError::new(&mut self.inner)) + } else { + Ok(&mut self.inner) + } + } +} + +impl Poisonable { + /// Consumes this `Poisonable`, returning the underlying data. + /// + /// # Errors + /// + /// If another user of this lock panicked while holding the lock, then this + /// call will return an error instead. + /// + /// # Examples + /// + /// ``` + /// use happylock::{Mutex, Poisonable}; + /// + /// let mutex = Poisonable::new(Mutex::new(0)); + /// assert_eq!(mutex.into_inner().unwrap(), 0); + /// ``` + pub fn into_inner(self) -> PoisonResult { + if self.is_poisoned() { + Err(PoisonError::new(self.inner.into_inner())) + } else { + Ok(self.inner.into_inner()) + } + } +} + +impl Poisonable { + /// Returns a mutable reference to the underlying data. + /// /// Since this call borrows the `Poisonable` mutable, no actual locking /// needs to take place - the mutable borrow statically guarantees no locks /// exist. @@ -310,14 +362,14 @@ impl Poisonable { /// /// let key = ThreadKey::get().unwrap(); /// let mut mutex = Poisonable::new(Mutex::new(0)); - /// *mutex.get_mut().unwrap().as_mut() = 10; + /// *mutex.get_mut().unwrap() = 10; /// assert_eq!(*mutex.lock(key).unwrap(), 10); /// ``` - pub fn get_mut(&mut self) -> PoisonResult<&mut L> { + pub fn get_mut(&mut self) -> PoisonResult<&mut L::Inner> { if self.is_poisoned() { - Err(PoisonError::new(&mut self.inner)) + Err(PoisonError::new(self.inner.as_mut())) } else { - Ok(&mut self.inner) + Ok(self.inner.as_mut()) } } } -- cgit v1.2.3