diff options
Diffstat (limited to 'ecs/src/lock.rs')
-rw-r--r-- | ecs/src/lock.rs | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/ecs/src/lock.rs b/ecs/src/lock.rs index 0b36922..d21b697 100644 --- a/ecs/src/lock.rs +++ b/ecs/src/lock.rs @@ -81,21 +81,26 @@ pub struct ReadGuard<'guard, Value> impl<'guard, Value> ReadGuard<'guard, Value> { - pub fn map<NewValue>( - self, - func: impl FnOnce(&Value) -> &NewValue, - ) -> MappedReadGuard<'guard, NewValue> + pub fn try_map<NewValue>( + this: Self, + func: impl FnOnce(&Value) -> Option<&NewValue>, + ) -> Result<MappedReadGuard<'guard, NewValue>, Self> { - let value_type_name = self.value_type_name; + let value_type_name = this.value_type_name; // The 'inner' field cannot be moved out of ReadGuard in a normal way since // ReadGuard implements Drop - let inner = unsafe { std::ptr::read(&self.inner) }; - forget(self); - - MappedReadGuard { - inner: RwLockReadGuard::map(inner, func), - value_type_name, + let inner = unsafe { std::ptr::read(&this.inner) }; + forget(this); + + match RwLockReadGuard::try_map(inner, func) { + Ok(mapped_guard) => { + Ok(MappedReadGuard { inner: mapped_guard, value_type_name }) + } + Err(unmapped_guard) => Err(Self { + inner: unmapped_guard, + value_type_name, + }), } } } @@ -155,21 +160,26 @@ pub struct WriteGuard<'guard, Value> impl<'guard, Value> WriteGuard<'guard, Value> { - pub fn map<NewValue>( - self, - func: impl FnOnce(&mut Value) -> &mut NewValue, - ) -> MappedWriteGuard<'guard, NewValue> + pub fn try_map<NewValue>( + this: Self, + func: impl FnOnce(&mut Value) -> Option<&mut NewValue>, + ) -> Result<MappedWriteGuard<'guard, NewValue>, Self> { - let value_type_name = self.value_type_name; + let value_type_name = this.value_type_name; // The 'inner' field cannot be moved out of ReadGuard in a normal way since // ReadGuard implements Drop - let inner = unsafe { std::ptr::read(&self.inner) }; - forget(self); - - MappedWriteGuard { - inner: RwLockWriteGuard::map(inner, func), - value_type_name, + let inner = unsafe { std::ptr::read(&this.inner) }; + forget(this); + + match RwLockWriteGuard::try_map(inner, func) { + Ok(mapped_guard) => { + Ok(MappedWriteGuard { inner: mapped_guard, value_type_name }) + } + Err(unmapped_guard) => Err(Self { + inner: unmapped_guard, + value_type_name, + }), } } } |