diff --git a/packages/signals/src/read.rs b/packages/signals/src/read.rs index 42442f675..98e8b1bce 100644 --- a/packages/signals/src/read.rs +++ b/packages/signals/src/read.rs @@ -419,9 +419,19 @@ pub trait ReadableResultExt: Readable> { T: 'static, E: 'static, { - ::try_map(self.read(), |v| v.as_ref().ok()).ok_or( - ::map(self.read(), |v| v.as_ref().err().unwrap()), - ) + let read = self.read(); + match read.deref() { + Ok(_) => Ok(::map(read, |v| { + v.as_ref() + .ok() + .expect("Result variant changed between read and map") + })), + Err(_) => Err(::map(read, |v| { + v.as_ref() + .err() + .expect("Result variant changed between read and map") + })), + } } } diff --git a/packages/signals/src/write.rs b/packages/signals/src/write.rs index 13b4107fa..1d3c68966 100644 --- a/packages/signals/src/write.rs +++ b/packages/signals/src/write.rs @@ -447,6 +447,44 @@ pub trait WritableOptionExt: Writable> { impl WritableOptionExt for W where W: Writable> {} +/// An extension trait for [`Writable>`] that provides some convenience methods. +pub trait WritableResultExt: Writable> { + /// Unwraps the inner value mutably, panicking if the Result is an error. + #[track_caller] + fn unwrap_mut(&mut self) -> WritableRef<'_, Self, T> + where + T: 'static, + E: 'static, + { + WriteLock::filter_map(self.write(), |v| v.as_mut().ok()) + .expect("Tried to unwrap a Result that was an error") + } + + /// Attempts to mutably access the inner value of the Result. + #[track_caller] + fn as_mut(&mut self) -> Result, WritableRef<'_, Self, E>> + where + T: 'static, + E: 'static, + { + let write = self.write(); + match write.as_ref() { + Ok(_) => Ok(WriteLock::map(write, |v| { + v.as_mut() + .ok() + .expect("Result variant changed between read and write") + })), + Err(_) => Err(WriteLock::map(write, |v| { + v.as_mut() + .err() + .expect("Result variant changed between read and write") + })), + } + } +} + +impl WritableResultExt for W where W: Writable> {} + /// An extension trait for [`Writable>`] that provides some convenience methods. pub trait WritableVecExt: Writable> { /// Pushes a new value to the end of the vector.