ソースを参照

remove mappable and mappablemut traits

Evan Almloff 1 年間 前
コミット
e01f10e25d

+ 33 - 38
packages/generational-box/src/lib.rs

@@ -226,7 +226,7 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
 
     /// Try to read the value. Returns None if the value is no longer valid.
     #[track_caller]
-    pub fn try_read(&self) -> Result<S::Ref, BorrowError> {
+    pub fn try_read(&self) -> Result<S::Ref<T>, BorrowError> {
         if !self.validate() {
             return Err(BorrowError::Dropped(ValueDroppedError {
                 #[cfg(any(debug_assertions, feature = "debug_borrows"))]
@@ -258,13 +258,13 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
 
     /// Read the value. Panics if the value is no longer valid.
     #[track_caller]
-    pub fn read(&self) -> S::Ref {
+    pub fn read(&self) -> S::Ref<T> {
         self.try_read().unwrap()
     }
 
     /// Try to write the value. Returns None if the value is no longer valid.
     #[track_caller]
-    pub fn try_write(&self) -> Result<S::Mut, BorrowMutError> {
+    pub fn try_write(&self) -> Result<S::Mut<T>, BorrowMutError> {
         if !self.validate() {
             return Err(BorrowMutError::Dropped(ValueDroppedError {
                 #[cfg(any(debug_assertions, feature = "debug_borrows"))]
@@ -292,7 +292,7 @@ impl<T: 'static, S: Storage<T>> GenerationalBox<T, S> {
 
     /// Write the value. Panics if the value is no longer valid.
     #[track_caller]
-    pub fn write(&self) -> S::Mut {
+    pub fn write(&self) -> S::Mut<T> {
         self.try_write().unwrap()
     }
 
@@ -325,42 +325,37 @@ impl<T, S> Clone for GenerationalBox<T, S> {
     }
 }
 
-/// A trait for types that can be mapped.
-pub trait Mappable<T: ?Sized>: Deref<Target = T> {
-    /// The type after the mapping.
-    type Mapped<U: ?Sized + 'static>: Mappable<U> + Deref<Target = U>;
+/// A trait for a storage backing type. (RefCell, RwLock, etc.)
+pub trait Storage<Data = ()>: AnyStorage + 'static {
+    /// The reference this storage type returns.
+    type Ref<T: ?Sized + 'static>: Deref<Target = T>;
+    /// The mutable reference this storage type returns.
+    type Mut<T: ?Sized + 'static>: DerefMut<Target = T>;
 
-    /// Map the value.
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped<U>;
+    /// Try to map the mutable ref.
+    fn try_map_mut<T, U: ?Sized + 'static>(
+        mut_ref: Self::Mut<T>,
+        f: impl FnOnce(&mut T) -> Option<&mut U>,
+    ) -> Option<Self::Mut<U>>;
+
+    /// Map the mutable ref.
+    fn map_mut<T, U: ?Sized + 'static>(
+        mut_ref: Self::Mut<T>,
+        f: impl FnOnce(&mut T) -> &mut U,
+    ) -> Self::Mut<U> {
+        Self::try_map_mut(mut_ref, |v| Some(f(v))).unwrap()
+    }
 
-    /// Try to map the value.
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
+    /// Try to map the ref.
+    fn try_map<T, U: ?Sized + 'static>(
+        ref_: Self::Ref<T>,
         f: impl FnOnce(&T) -> Option<&U>,
-    ) -> Option<Self::Mapped<U>>;
-}
-
-/// A trait for types that can be mapped mutably.
-pub trait MappableMut<T: ?Sized>: DerefMut<Target = T> {
-    /// The type after the mapping.
-    type Mapped<U: ?Sized + 'static>: MappableMut<U> + DerefMut<Target = U>;
-
-    /// Map the value.
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&mut T) -> &mut U) -> Self::Mapped<U>;
+    ) -> Option<Self::Ref<U>>;
 
-    /// Try to map the value.
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&mut T) -> Option<&mut U>,
-    ) -> Option<Self::Mapped<U>>;
-}
-
-/// A trait for a storage backing type. (RefCell, RwLock, etc.)
-pub trait Storage<Data>: AnyStorage + 'static {
-    /// The reference this storage type returns.
-    type Ref: Mappable<Data> + Deref<Target = Data>;
-    /// The mutable reference this storage type returns.
-    type Mut: MappableMut<Data> + DerefMut<Target = Data>;
+    /// Map the ref.
+    fn map<T, U: ?Sized + 'static>(ref_: Self::Ref<T>, f: impl FnOnce(&T) -> &U) -> Self::Ref<U> {
+        Self::try_map(ref_, |v| Some(f(v))).unwrap()
+    }
 
     /// Try to read the value. Returns None if the value is no longer valid.
     fn try_read(
@@ -368,7 +363,7 @@ pub trait Storage<Data>: AnyStorage + 'static {
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
         created_at: &'static std::panic::Location<'static>,
         #[cfg(any(debug_assertions, feature = "debug_ownership"))] at: GenerationalRefBorrowInfo,
-    ) -> Result<Self::Ref, BorrowError>;
+    ) -> Result<Self::Ref<Data>, BorrowError>;
 
     /// Try to write the value. Returns None if the value is no longer valid.
     fn try_write(
@@ -376,7 +371,7 @@ pub trait Storage<Data>: AnyStorage + 'static {
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
         created_at: &'static std::panic::Location<'static>,
         #[cfg(any(debug_assertions, feature = "debug_ownership"))] at: GenerationalRefMutBorrowInfo,
-    ) -> Result<Self::Mut, BorrowMutError>;
+    ) -> Result<Self::Mut<Data>, BorrowMutError>;
 
     /// Set the value
     fn set(&'static self, value: Data);

+ 13 - 88
packages/generational-box/src/references.rs

@@ -1,83 +1,41 @@
 use std::{
     fmt::{Debug, Display},
-    marker::PhantomData,
     ops::{Deref, DerefMut},
 };
 
-use crate::{Mappable, MappableMut};
-
 /// A reference to a value in a generational box.
-pub struct GenerationalRef<T: ?Sized + 'static, R: Mappable<T>> {
-    inner: R,
-    phantom: PhantomData<T>,
+pub struct GenerationalRef<R> {
+    pub(crate) inner: R,
     #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-    borrow: GenerationalRefBorrowInfo,
+    pub(crate) borrow: GenerationalRefBorrowInfo,
 }
 
-impl<T: 'static, R: Mappable<T>> GenerationalRef<T, R> {
+impl<T: 'static, R: Deref<Target = T>> GenerationalRef<R> {
     pub(crate) fn new(
         inner: R,
         #[cfg(any(debug_assertions, feature = "debug_borrows"))] borrow: GenerationalRefBorrowInfo,
     ) -> Self {
         Self {
             inner,
-            phantom: PhantomData,
             #[cfg(any(debug_assertions, feature = "debug_borrows"))]
             borrow,
         }
     }
 }
 
-impl<T: ?Sized + 'static, R: Mappable<T>> Mappable<T> for GenerationalRef<T, R> {
-    type Mapped<U: ?Sized + 'static> = GenerationalRef<U, R::Mapped<U>>;
-
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped<U> {
-        GenerationalRef {
-            inner: R::map(_self.inner, f),
-            phantom: PhantomData,
-            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-            borrow: GenerationalRefBorrowInfo {
-                borrowed_at: _self.borrow.borrowed_at,
-                borrowed_from: _self.borrow.borrowed_from,
-            },
-        }
-    }
-
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&T) -> Option<&U>,
-    ) -> Option<Self::Mapped<U>> {
-        let Self {
-            inner,
-            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-            borrow,
-            ..
-        } = _self;
-        R::try_map(inner, f).map(|inner| GenerationalRef {
-            inner,
-            phantom: PhantomData,
-            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-            borrow: GenerationalRefBorrowInfo {
-                borrowed_at: borrow.borrowed_at,
-                borrowed_from: borrow.borrowed_from,
-            },
-        })
-    }
-}
-
-impl<T: ?Sized + Debug, R: Mappable<T>> Debug for GenerationalRef<T, R> {
+impl<T: ?Sized + Debug, R: Deref<Target = T>> Debug for GenerationalRef<R> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         self.inner.deref().fmt(f)
     }
 }
 
-impl<T: ?Sized + Display, R: Mappable<T>> Display for GenerationalRef<T, R> {
+impl<T: ?Sized + Display, R: Deref<Target = T>> Display for GenerationalRef<R> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         self.inner.deref().fmt(f)
     }
 }
 
-impl<T: ?Sized + 'static, R: Mappable<T>> Deref for GenerationalRef<T, R> {
+impl<T: ?Sized + 'static, R: Deref<Target = T>> Deref for GenerationalRef<R> {
     type Target = T;
 
     fn deref(&self) -> &Self::Target {
@@ -103,14 +61,13 @@ impl Drop for GenerationalRefBorrowInfo {
 }
 
 /// A mutable reference to a value in a generational box.
-pub struct GenerationalRefMut<T: ?Sized + 'static, W: MappableMut<T>> {
-    inner: W,
-    phantom: PhantomData<T>,
+pub struct GenerationalRefMut<W> {
+    pub(crate) inner: W,
     #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-    borrow: GenerationalRefMutBorrowInfo,
+    pub(crate) borrow: GenerationalRefMutBorrowInfo,
 }
 
-impl<T: 'static, R: MappableMut<T>> GenerationalRefMut<T, R> {
+impl<T: 'static, R: DerefMut<Target = T>> GenerationalRefMut<R> {
     pub(crate) fn new(
         inner: R,
         #[cfg(any(debug_assertions, feature = "debug_borrows"))]
@@ -118,45 +75,13 @@ impl<T: 'static, R: MappableMut<T>> GenerationalRefMut<T, R> {
     ) -> Self {
         Self {
             inner,
-            phantom: PhantomData,
             #[cfg(any(debug_assertions, feature = "debug_borrows"))]
             borrow,
         }
     }
 }
 
-impl<T: ?Sized + 'static, W: MappableMut<T>> MappableMut<T> for GenerationalRefMut<T, W> {
-    type Mapped<U: ?Sized + 'static> = GenerationalRefMut<U, W::Mapped<U>>;
-
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&mut T) -> &mut U) -> Self::Mapped<U> {
-        GenerationalRefMut {
-            inner: W::map(_self.inner, f),
-            phantom: PhantomData,
-            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-            borrow: _self.borrow,
-        }
-    }
-
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&mut T) -> Option<&mut U>,
-    ) -> Option<Self::Mapped<U>> {
-        let Self {
-            inner,
-            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-            borrow,
-            ..
-        } = _self;
-        W::try_map(inner, f).map(|inner| GenerationalRefMut {
-            inner,
-            phantom: PhantomData,
-            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
-            borrow,
-        })
-    }
-}
-
-impl<T: ?Sized + 'static, W: MappableMut<T>> Deref for GenerationalRefMut<T, W> {
+impl<T: ?Sized + 'static, W: DerefMut<Target = T>> Deref for GenerationalRefMut<W> {
     type Target = T;
 
     fn deref(&self) -> &Self::Target {
@@ -164,7 +89,7 @@ impl<T: ?Sized + 'static, W: MappableMut<T>> Deref for GenerationalRefMut<T, W>
     }
 }
 
-impl<T: ?Sized + 'static, W: MappableMut<T>> DerefMut for GenerationalRefMut<T, W> {
+impl<T: ?Sized + 'static, W: DerefMut<Target = T>> DerefMut for GenerationalRefMut<W> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         self.inner.deref_mut()
     }

+ 49 - 35
packages/generational-box/src/sync.rs

@@ -6,7 +6,8 @@ use std::sync::{Arc, OnceLock};
 use crate::{
     error::{self, ValueDroppedError},
     references::{GenerationalRef, GenerationalRefMut},
-    AnyStorage, Mappable, MappableMut, MemoryLocation, MemoryLocationInner, Storage,
+    AnyStorage, GenerationalRefBorrowInfo, GenerationalRefMutBorrowInfo, MemoryLocation,
+    MemoryLocationInner, Storage,
 };
 
 /// A thread safe storage. This is slower than the unsync storage, but allows you to share the value between threads.
@@ -48,39 +49,9 @@ impl AnyStorage for SyncStorage {
     }
 }
 
-impl<T: ?Sized> Mappable<T> for MappedRwLockReadGuard<'static, T> {
-    type Mapped<U: ?Sized + 'static> = MappedRwLockReadGuard<'static, U>;
-
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped<U> {
-        MappedRwLockReadGuard::map(_self, f)
-    }
-
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&T) -> Option<&U>,
-    ) -> Option<Self::Mapped<U>> {
-        MappedRwLockReadGuard::try_map(_self, f).ok()
-    }
-}
-
-impl<T: ?Sized> MappableMut<T> for MappedRwLockWriteGuard<'static, T> {
-    type Mapped<U: ?Sized + 'static> = MappedRwLockWriteGuard<'static, U>;
-
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&mut T) -> &mut U) -> Self::Mapped<U> {
-        MappedRwLockWriteGuard::map(_self, f)
-    }
-
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&mut T) -> Option<&mut U>,
-    ) -> Option<Self::Mapped<U>> {
-        MappedRwLockWriteGuard::try_map(_self, f).ok()
-    }
-}
-
 impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
-    type Ref = GenerationalRef<T, MappedRwLockReadGuard<'static, T>>;
-    type Mut = GenerationalRefMut<T, MappedRwLockWriteGuard<'static, T>>;
+    type Ref<R: ?Sized + 'static> = GenerationalRef<MappedRwLockReadGuard<'static, R>>;
+    type Mut<W: ?Sized + 'static> = GenerationalRefMut<MappedRwLockWriteGuard<'static, W>>;
 
     fn try_read(
         &'static self,
@@ -88,7 +59,7 @@ impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
         created_at: &'static std::panic::Location<'static>,
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
         at: crate::GenerationalRefBorrowInfo,
-    ) -> Result<Self::Ref, error::BorrowError> {
+    ) -> Result<Self::Ref<T>, error::BorrowError> {
         let read = self.0.try_read();
 
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
@@ -121,7 +92,7 @@ impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
         created_at: &'static std::panic::Location<'static>,
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
         at: crate::GenerationalRefMutBorrowInfo,
-    ) -> Result<Self::Mut, error::BorrowMutError> {
+    ) -> Result<Self::Mut<T>, error::BorrowMutError> {
         let write = self.0.try_write();
 
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
@@ -151,4 +122,47 @@ impl<T: Sync + Send + 'static> Storage<T> for SyncStorage {
     fn set(&self, value: T) {
         *self.0.write() = Some(Box::new(value));
     }
+
+    fn try_map<I, U: ?Sized + 'static>(
+        ref_: Self::Ref<I>,
+        f: impl FnOnce(&I) -> Option<&U>,
+    ) -> Option<Self::Ref<U>> {
+        let GenerationalRef {
+            inner,
+            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+            borrow,
+            ..
+        } = ref_;
+        MappedRwLockReadGuard::try_map(inner, f)
+            .ok()
+            .map(|inner| GenerationalRef {
+                inner,
+                #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+                borrow: GenerationalRefBorrowInfo {
+                    borrowed_at: borrow.borrowed_at,
+                    borrowed_from: borrow.borrowed_from,
+                },
+            })
+    }
+
+    fn try_map_mut<I, U: ?Sized + 'static>(
+        mut_ref: Self::Mut<I>,
+        f: impl FnOnce(&mut I) -> Option<&mut U>,
+    ) -> Option<Self::Mut<U>> {
+        let GenerationalRefMut {
+            inner,
+            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+            borrow,
+            ..
+        } = mut_ref;
+        MappedRwLockWriteGuard::try_map(inner, f)
+            .ok()
+            .map(|inner| GenerationalRefMut {
+                inner,
+                #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+                borrow: GenerationalRefMutBorrowInfo {
+                    borrowed_from: borrow.borrowed_from,
+                },
+            })
+    }
 }

+ 43 - 35
packages/generational-box/src/unsync.rs

@@ -1,7 +1,7 @@
 use crate::{
     error,
     references::{GenerationalRef, GenerationalRefMut},
-    AnyStorage, Mappable, MappableMut, MemoryLocation, MemoryLocationInner, Storage,
+    AnyStorage, GenerationalRefMutBorrowInfo, MemoryLocation, MemoryLocationInner, Storage,
 };
 use std::cell::{Ref, RefCell, RefMut};
 
@@ -14,39 +14,9 @@ impl Default for UnsyncStorage {
     }
 }
 
-impl<T: ?Sized> Mappable<T> for Ref<'static, T> {
-    type Mapped<U: ?Sized + 'static> = Ref<'static, U>;
-
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&T) -> &U) -> Self::Mapped<U> {
-        Ref::map(_self, f)
-    }
-
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&T) -> Option<&U>,
-    ) -> Option<Self::Mapped<U>> {
-        Ref::filter_map(_self, f).ok()
-    }
-}
-
-impl<T: ?Sized> MappableMut<T> for RefMut<'static, T> {
-    type Mapped<U: ?Sized + 'static> = RefMut<'static, U>;
-
-    fn map<U: ?Sized + 'static>(_self: Self, f: impl FnOnce(&mut T) -> &mut U) -> Self::Mapped<U> {
-        RefMut::map(_self, f)
-    }
-
-    fn try_map<U: ?Sized + 'static>(
-        _self: Self,
-        f: impl FnOnce(&mut T) -> Option<&mut U>,
-    ) -> Option<Self::Mapped<U>> {
-        RefMut::filter_map(_self, f).ok()
-    }
-}
-
 impl<T: 'static> Storage<T> for UnsyncStorage {
-    type Ref = GenerationalRef<T, Ref<'static, T>>;
-    type Mut = GenerationalRefMut<T, RefMut<'static, T>>;
+    type Ref<R: ?Sized + 'static> = GenerationalRef<Ref<'static, R>>;
+    type Mut<W: ?Sized + 'static> = GenerationalRefMut<RefMut<'static, W>>;
 
     fn try_read(
         &'static self,
@@ -54,7 +24,7 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
         created_at: &'static std::panic::Location<'static>,
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
         at: crate::GenerationalRefBorrowInfo,
-    ) -> Result<Self::Ref, error::BorrowError> {
+    ) -> Result<Self::Ref<T>, error::BorrowError> {
         let borrow = self.0.try_borrow();
 
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
@@ -87,7 +57,7 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
         created_at: &'static std::panic::Location<'static>,
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
         at: crate::GenerationalRefMutBorrowInfo,
-    ) -> Result<Self::Mut, error::BorrowMutError> {
+    ) -> Result<Self::Mut<T>, error::BorrowMutError> {
         let borrow = self.0.try_borrow_mut();
 
         #[cfg(any(debug_assertions, feature = "debug_ownership"))]
@@ -116,6 +86,44 @@ impl<T: 'static> Storage<T> for UnsyncStorage {
     fn set(&self, value: T) {
         *self.0.borrow_mut() = Some(Box::new(value));
     }
+
+    fn try_map<I, U: ?Sized + 'static>(
+        _self: Self::Ref<I>,
+        f: impl FnOnce(&I) -> Option<&U>,
+    ) -> Option<Self::Ref<U>> {
+        let GenerationalRef {
+            inner,
+            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+            borrow,
+            ..
+        } = _self;
+        Ref::filter_map(inner, f).ok().map(|inner| GenerationalRef {
+            inner,
+            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+            borrow,
+        })
+    }
+
+    fn try_map_mut<I, U: ?Sized + 'static>(
+        mut_ref: Self::Mut<I>,
+        f: impl FnOnce(&mut I) -> Option<&mut U>,
+    ) -> Option<Self::Mut<U>> {
+        let GenerationalRefMut {
+            inner,
+            #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+            borrow,
+            ..
+        } = mut_ref;
+        RefMut::filter_map(inner, f)
+            .ok()
+            .map(|inner| GenerationalRefMut {
+                inner,
+                #[cfg(any(debug_assertions, feature = "debug_borrows"))]
+                borrow: GenerationalRefMutBorrowInfo {
+                    borrowed_from: borrow.borrowed_from,
+                },
+            })
+    }
 }
 
 thread_local! {

+ 9 - 9
packages/signals/src/global.rs

@@ -1,10 +1,10 @@
 use dioxus_core::prelude::{
     provide_root_context, try_consume_context, IntoAttributeValue, ScopeId,
 };
-use generational_box::{GenerationalRef, GenerationalRefMut};
+use generational_box::GenerationalRef;
 use std::{
     any::Any,
-    cell::{Ref, RefCell, RefMut},
+    cell::{Ref, RefCell},
     collections::HashMap,
     mem::MaybeUninit,
     ops::Deref,
@@ -48,7 +48,7 @@ impl<T: 'static> GlobalSignal<T> {
         let read = context.signal.borrow();
 
         match read.get(&key) {
-            Some(signal) => signal.downcast_ref::<Signal<T>>().unwrap().clone(),
+            Some(signal) => *signal.downcast_ref::<Signal<T>>().unwrap(),
             None => {
                 drop(read);
 
@@ -74,14 +74,14 @@ impl<T: 'static> GlobalSignal<T> {
     ///
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn read(&self) -> GenerationalRef<T, Ref<'static, T>> {
+    pub fn read(&self) -> GenerationalRef<Ref<'static, T>> {
         self.signal().read()
     }
 
     /// Get the current value of the signal. **Unlike read, this will not subscribe the current scope to the signal which can cause parts of your UI to not update.**
     ///
     /// If the signal has been dropped, this will panic.
-    pub fn peek(&self) -> GenerationalRef<T, Ref<'static, T>> {
+    pub fn peek(&self) -> GenerationalRef<Ref<'static, T>> {
         self.signal().peek()
     }
 
@@ -89,7 +89,7 @@ impl<T: 'static> GlobalSignal<T> {
     ///
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn write(&self) -> Write<T, GenerationalRefMut<T, RefMut<'static, T>>> {
+    pub fn write(&self) -> Write<T> {
         self.signal().write()
     }
 
@@ -123,7 +123,7 @@ impl<T: 'static> GlobalSignal<T> {
     pub fn map<O>(
         &self,
         f: impl Fn(&T) -> &O + 'static,
-    ) -> MappedSignal<GenerationalRef<O, Ref<'static, O>>> {
+    ) -> MappedSignal<GenerationalRef<Ref<'static, O>>> {
         MappedSignal::new(self.signal(), f)
     }
 
@@ -242,14 +242,14 @@ impl<T: PartialEq + 'static> GlobalMemo<T> {
     ///
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn read(&self) -> GenerationalRef<T, Ref<'static, T>> {
+    pub fn read(&self) -> GenerationalRef<Ref<'static, T>> {
         self.signal().read()
     }
 
     /// Get the current value of the signal. **Unlike read, this will not subscribe the current scope to the signal which can cause parts of your UI to not update.**
     ///
     /// If the signal has been dropped, this will panic.
-    pub fn peek(&self) -> GenerationalRef<T, Ref<'static, T>> {
+    pub fn peek(&self) -> GenerationalRef<Ref<'static, T>> {
         self.signal().peek()
     }
 

+ 41 - 94
packages/signals/src/impls.rs

@@ -1,8 +1,8 @@
 use crate::rt::CopyValue;
 use crate::signal::{ReadOnlySignal, Signal, Write};
 use crate::{GlobalMemo, GlobalSignal, SignalData};
-use generational_box::{GenerationalRef, Mappable};
-use generational_box::{MappableMut, Storage};
+use generational_box::Storage;
+use generational_box::{GenerationalRef, UnsyncStorage};
 
 use std::cell::Ref;
 use std::{
@@ -208,8 +208,8 @@ read_impls!(CopyValue, S: Storage<T>, S: Storage<Vec<T>>);
 impl<T: 'static, S: Storage<Vec<T>>> CopyValue<Vec<T>, S> {
     /// Read a value from the inner vector.
     #[track_caller]
-    pub fn get(&self, index: usize) -> Option<<S::Ref as Mappable<Vec<T>>>::Mapped<T>> {
-        S::Ref::try_map(self.read(), move |v| v.get(index))
+    pub fn get(&self, index: usize) -> Option<S::Ref<T>> {
+        S::try_map(self.read(), move |v| v.get(index))
     }
 }
 
@@ -225,8 +225,8 @@ impl<T: 'static, S: Storage<Option<T>>> CopyValue<Option<T>, S> {
 
     /// Attempts to read the inner value of the Option.
     #[track_caller]
-    pub fn as_ref(&self) -> Option<<S::Ref as Mappable<Option<T>>>::Mapped<T>> {
-        S::Ref::try_map(self.read(), |v| v.as_ref())
+    pub fn as_ref(&self) -> Option<S::Ref<T>> {
+        S::try_map(self.read(), |v| v.as_ref())
     }
 }
 
@@ -247,23 +247,20 @@ impl<T: 'static, S: Storage<Option<T>>> CopyValue<Option<T>, S> {
 
     /// Gets the value out of the Option, or inserts the given value if the Option is empty.
     #[track_caller]
-    pub fn get_or_insert(&self, default: T) -> <S::Ref as Mappable<Option<T>>>::Mapped<T> {
+    pub fn get_or_insert(&self, default: T) -> S::Ref<T> {
         self.get_or_insert_with(|| default)
     }
 
     /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty.
     #[track_caller]
-    pub fn get_or_insert_with(
-        &self,
-        default: impl FnOnce() -> T,
-    ) -> <S::Ref as Mappable<Option<T>>>::Mapped<T> {
+    pub fn get_or_insert_with(&self, default: impl FnOnce() -> T) -> S::Ref<T> {
         let borrow = self.read();
         if borrow.is_none() {
             drop(borrow);
             self.with_mut(|v| *v = Some(default()));
-            S::Ref::map(self.read(), |v| v.as_ref().unwrap())
+            S::map(self.read(), |v| v.as_ref().unwrap())
         } else {
-            S::Ref::map(borrow, |v| v.as_ref().unwrap())
+            S::map(borrow, |v| v.as_ref().unwrap())
         }
     }
 }
@@ -272,15 +269,8 @@ read_impls!(Signal, S: Storage<SignalData<T>>, S: Storage<SignalData<Vec<T>>>);
 
 impl<T: 'static, S: Storage<SignalData<Vec<T>>>> Signal<Vec<T>, S> {
     /// Read a value from the inner vector.
-    pub fn get(
-        &self,
-        index: usize,
-    ) -> Option<
-        <<<S as Storage<SignalData<Vec<T>>>>::Ref as Mappable<SignalData<Vec<T>>>>::Mapped<Vec<T>> as Mappable<
-            Vec<T>,
-        >>::Mapped<T>,
-    >{
-        <<S as Storage<SignalData<Vec<T>>>>::Ref as Mappable<SignalData<Vec<T>>>>::Mapped::<Vec<T>>::try_map(self.read(), move |v| v.get(index))
+    pub fn get(&self, index: usize) -> Option<S::Ref<T>> {
+        S::try_map(self.read(), move |v| v.get(index))
     }
 }
 
@@ -294,16 +284,8 @@ impl<T: 'static, S: Storage<SignalData<Option<T>>>> Signal<Option<T>, S> {
     }
 
     /// Attempts to read the inner value of the Option.
-    pub fn as_ref(
-        &self,
-    ) -> Option<
-        <<<S as Storage<SignalData<Option<T>>>>::Ref as Mappable<SignalData<Option<T>>>>::Mapped<
-            Option<T>,
-        > as Mappable<Option<T>>>::Mapped<T>,
-    > {
-        <<S as Storage<SignalData<Option<T>>>>::Ref as Mappable<SignalData<Option<T>>>>::Mapped::<
-            Option<T>,
-        >::try_map(self.read(), |v| v.as_ref())
+    pub fn as_ref(&self) -> Option<S::Ref<T>> {
+        S::try_map(self.read(), |v| v.as_ref())
     }
 }
 
@@ -321,27 +303,19 @@ impl<T: 'static, S: Storage<SignalData<Option<T>>>> Signal<Option<T>, S> {
     }
 
     /// Gets the value out of the Option, or inserts the given value if the Option is empty.
-    pub fn get_or_insert(&mut self, default: T) -> <<S::Ref as Mappable<SignalData<Option<T>>>>::Mapped<Option<T>> as Mappable<Option<T>>>::Mapped<T>{
+    pub fn get_or_insert(&mut self, default: T) -> S::Ref<T> {
         self.get_or_insert_with(|| default)
     }
 
     /// Gets the value out of the Option, or inserts the value returned by the given function if the Option is empty.
-    pub fn get_or_insert_with(
-        &mut self,
-        default: impl FnOnce() -> T,
-    ) -><<S::Ref as Mappable<SignalData<Option<T>>>>::Mapped<Option<T>> as Mappable<Option<T>>>::Mapped<T>{
+    pub fn get_or_insert_with(&mut self, default: impl FnOnce() -> T) -> S::Ref<T> {
         let borrow = self.read();
         if borrow.is_none() {
             drop(borrow);
             self.with_mut(|v| *v = Some(default()));
-            <S::Ref as Mappable<SignalData<Option<T>>>>::Mapped::<Option<T>>::map(
-                self.read(),
-                |v| v.as_ref().unwrap(),
-            )
+            S::map(self.read(), |v| v.as_ref().unwrap())
         } else {
-            <S::Ref as Mappable<SignalData<Option<T>>>>::Mapped::<Option<T>>::map(borrow, |v| {
-                v.as_ref().unwrap()
-            })
+            S::map(borrow, |v| v.as_ref().unwrap())
         }
     }
 }
@@ -356,8 +330,8 @@ read_impls!(GlobalSignal);
 
 impl<T: 'static> GlobalSignal<Vec<T>> {
     /// Read a value from the inner vector.
-    pub fn get(&'static self, index: usize) -> Option<GenerationalRef<T, Ref<'static, T>>> {
-        GenerationalRef::<Vec<T>, Ref<'static, Vec<T>>>::try_map(self.read(), move |v| v.get(index))
+    pub fn get(&'static self, index: usize) -> Option<GenerationalRef<Ref<'static, T>>> {
+        <UnsyncStorage as Storage>::try_map(self.read(), move |v| v.get(index))
     }
 }
 
@@ -371,8 +345,8 @@ impl<T: 'static> GlobalSignal<Option<T>> {
     }
 
     /// Attempts to read the inner value of the Option.
-    pub fn as_ref(&'static self) -> Option<GenerationalRef<T, Ref<'static, T>>> {
-        GenerationalRef::<Option<T>, Ref<'static, Option<T>>>::try_map(self.read(), |v| v.as_ref())
+    pub fn as_ref(&'static self) -> Option<GenerationalRef<Ref<'static, T>>> {
+        <UnsyncStorage as Storage>::try_map(self.read(), |v| v.as_ref())
     }
 }
 
@@ -390,7 +364,7 @@ impl<T: 'static> GlobalSignal<Option<T>> {
     }
 
     /// Gets the value out of the Option, or inserts the given value if the Option is empty.
-    pub fn get_or_insert(&self, default: T) -> GenerationalRef<T, Ref<'static, T>> {
+    pub fn get_or_insert(&self, default: T) -> GenerationalRef<Ref<'static, T>> {
         self.get_or_insert_with(|| default)
     }
 
@@ -398,18 +372,14 @@ impl<T: 'static> GlobalSignal<Option<T>> {
     pub fn get_or_insert_with(
         &self,
         default: impl FnOnce() -> T,
-    ) -> GenerationalRef<T, Ref<'static, T>> {
+    ) -> GenerationalRef<Ref<'static, T>> {
         let borrow = self.read();
         if borrow.is_none() {
             drop(borrow);
             self.with_mut(|v| *v = Some(default()));
-            GenerationalRef::<Option<T>, Ref<'static, Option<T>>>::map(self.read(), |v| {
-                v.as_ref().unwrap()
-            })
+            <UnsyncStorage as Storage>::map(self.read(), |v| v.as_ref().unwrap())
         } else {
-            GenerationalRef::<Option<T>, Ref<'static, Option<T>>>::map(borrow, |v| {
-                v.as_ref().unwrap()
-            })
+            <UnsyncStorage as Storage>::map(borrow, |v| v.as_ref().unwrap())
         }
     }
 }
@@ -418,8 +388,8 @@ read_impls!(GlobalMemo: PartialEq);
 
 impl<T: PartialEq + 'static> GlobalMemo<Vec<T>> {
     /// Read a value from the inner vector.
-    pub fn get(&'static self, index: usize) -> Option<GenerationalRef<T, Ref<'static, T>>> {
-        GenerationalRef::<Vec<T>, Ref<'static, Vec<T>>>::try_map(self.read(), move |v| v.get(index))
+    pub fn get(&'static self, index: usize) -> Option<GenerationalRef<Ref<'static, T>>> {
+        <UnsyncStorage as Storage>::try_map(self.read(), move |v| v.get(index))
     }
 }
 
@@ -433,8 +403,8 @@ impl<T: PartialEq + 'static> GlobalMemo<Option<T>> {
     }
 
     /// Attempts to read the inner value of the Option.
-    pub fn as_ref(&'static self) -> Option<GenerationalRef<T, Ref<'static, T>>> {
-        GenerationalRef::<Option<T>, Ref<'static, Option<T>>>::try_map(self.read(), |v| v.as_ref())
+    pub fn as_ref(&'static self) -> Option<GenerationalRef<Ref<'static, T>>> {
+        <UnsyncStorage as Storage>::try_map(self.read(), |v| v.as_ref())
     }
 }
 
@@ -445,7 +415,7 @@ pub struct CopyValueIterator<T: 'static, S: Storage<Vec<T>>> {
 }
 
 impl<T, S: Storage<Vec<T>>> Iterator for CopyValueIterator<T, S> {
-    type Item = <S::Ref as Mappable<Vec<T>>>::Mapped<T>;
+    type Item = S::Ref<T>;
 
     fn next(&mut self) -> Option<Self::Item> {
         let index = self.index;
@@ -457,7 +427,7 @@ impl<T, S: Storage<Vec<T>>> Iterator for CopyValueIterator<T, S> {
 impl<T: 'static, S: Storage<Vec<T>>> IntoIterator for CopyValue<Vec<T>, S> {
     type IntoIter = CopyValueIterator<T, S>;
 
-    type Item = <S::Ref as Mappable<Vec<T>>>::Mapped<T>;
+    type Item = S::Ref<T>;
 
     fn into_iter(self) -> Self::IntoIter {
         CopyValueIterator {
@@ -469,17 +439,15 @@ impl<T: 'static, S: Storage<Vec<T>>> IntoIterator for CopyValue<Vec<T>, S> {
 
 impl<T: 'static, S: Storage<Vec<T>>> CopyValue<Vec<T>, S> {
     /// Write to an element in the inner vector.
-    pub fn get_mut(&self, index: usize) -> Option<<S::Mut as MappableMut<Vec<T>>>::Mapped<T>> {
-        S::Mut::try_map(self.write(), |v: &mut Vec<T>| v.get_mut(index))
+    pub fn get_mut(&self, index: usize) -> Option<S::Mut<T>> {
+        S::try_map_mut(self.write(), |v: &mut Vec<T>| v.get_mut(index))
     }
 }
 
 impl<T: 'static, S: Storage<Option<T>>> CopyValue<Option<T>, S> {
     /// Deref the inner value mutably.
-    pub fn as_mut(
-        &self,
-    ) -> Option<<<S as Storage<Option<T>>>::Mut as MappableMut<Option<T>>>::Mapped<T>> {
-        S::Mut::try_map(self.write(), |v: &mut Option<T>| v.as_mut())
+    pub fn as_mut(&self) -> Option<S::Mut<T>> {
+        S::try_map_mut(self.write(), |v: &mut Option<T>| v.as_mut())
     }
 }
 
@@ -490,9 +458,7 @@ pub struct SignalIterator<T: 'static, S: Storage<SignalData<Vec<T>>>> {
 }
 
 impl<T, S: Storage<SignalData<Vec<T>>>> Iterator for SignalIterator<T, S> {
-    type Item = <<<S as Storage<SignalData<Vec<T>>>>::Ref as Mappable<SignalData<Vec<T>>>>::Mapped<
-        Vec<T>,
-    > as Mappable<Vec<T>>>::Mapped<T>;
+    type Item = S::Ref<T>;
 
     fn next(&mut self) -> Option<Self::Item> {
         let index = self.index;
@@ -504,9 +470,7 @@ impl<T, S: Storage<SignalData<Vec<T>>>> Iterator for SignalIterator<T, S> {
 impl<T: 'static, S: Storage<SignalData<Vec<T>>>> IntoIterator for Signal<Vec<T>, S> {
     type IntoIter = SignalIterator<T, S>;
 
-    type Item = <<<S as Storage<SignalData<Vec<T>>>>::Ref as Mappable<SignalData<Vec<T>>>>::Mapped<
-        Vec<T>,
-    > as Mappable<Vec<T>>>::Mapped<T>;
+    type Item = S::Ref<T>;
 
     fn into_iter(self) -> Self::IntoIter {
         SignalIterator {
@@ -516,33 +480,16 @@ impl<T: 'static, S: Storage<SignalData<Vec<T>>>> IntoIterator for Signal<Vec<T>,
     }
 }
 
-impl<T: 'static, S: Storage<SignalData<Vec<T>>>> Signal<Vec<T>, S>
-where
-    <<S as Storage<SignalData<std::vec::Vec<T>>>>::Mut as MappableMut<
-        SignalData<std::vec::Vec<T>>,
-    >>::Mapped<std::vec::Vec<T>>: MappableMut<std::vec::Vec<T>>,
-{
+impl<T: 'static, S: Storage<SignalData<Vec<T>>>> Signal<Vec<T>, S> {
     /// Returns a reference to an element or `None` if out of bounds.
-    pub fn get_mut(
-        &mut self,
-        index: usize,
-    ) -> Option<
-        Write<
-            T,
-            <<<S as Storage<SignalData<Vec<T>>>>::Mut as MappableMut<SignalData<Vec<T>>>>::Mapped<
-                Vec<T>,
-            > as MappableMut<Vec<T>>>::Mapped<T>,
-            S,
-            Vec<T>,
-        >,
-    > {
+    pub fn get_mut(&mut self, index: usize) -> Option<Write<T, S, Vec<T>>> {
         Write::filter_map(self.write(), |v| v.get_mut(index))
     }
 }
 
 impl<T: 'static, S: Storage<SignalData<Option<T>>>> Signal<Option<T>, S> {
     /// Returns a reference to an element or `None` if out of bounds.
-    pub fn as_mut(&mut self) -> Option<Write<T, <<<S as Storage<SignalData<Option<T>>>>::Mut as MappableMut<SignalData<Option<T>>>>::Mapped<Option<T>> as MappableMut<Option<T>>>::Mapped<T>, S, Option<T>>>{
+    pub fn as_mut(&mut self) -> Option<Write<T, S, Option<T>>> {
         Write::filter_map(self.write(), |v| v.as_mut())
     }
 }

+ 2 - 12
packages/signals/src/map.rs

@@ -2,7 +2,6 @@ use crate::CopyValue;
 use crate::Signal;
 use crate::SignalData;
 use dioxus_core::ScopeId;
-use generational_box::Mappable;
 use generational_box::Storage;
 use std::fmt::Debug;
 use std::fmt::Display;
@@ -18,19 +17,10 @@ impl MappedSignal<()> {
     pub fn new<T, S: Storage<SignalData<T>>, U: ?Sized>(
         signal: Signal<T, S>,
         mapping: impl Fn(&T) -> &U + 'static,
-    ) -> MappedSignal<
-        <<<S as generational_box::Storage<SignalData<T>>>::Ref as Mappable<SignalData<T>>>::Mapped<
-            T,
-        > as generational_box::Mappable<T>>::Mapped<U>,
-    > {
+    ) -> MappedSignal<S::Ref<U>> {
         MappedSignal {
             origin_scope: signal.origin_scope(),
-            mapping: CopyValue::new(Box::new(move || {
-                <<<S as Storage<SignalData<T>>>::Ref as Mappable<SignalData<T>>>::Mapped<T>>::map(
-                    signal.read(),
-                    &mapping,
-                )
-            })),
+            mapping: CopyValue::new(Box::new(move || S::map(signal.read(), &mapping))),
         }
     }
 }

+ 5 - 5
packages/signals/src/rt.rs

@@ -142,19 +142,19 @@ impl<T: 'static, S: Storage<T>> CopyValue<T, S> {
 
     /// Try to read the value. If the value has been dropped, this will return None.
     #[track_caller]
-    pub fn try_read(&self) -> Result<S::Ref, generational_box::BorrowError> {
+    pub fn try_read(&self) -> Result<S::Ref<T>, generational_box::BorrowError> {
         self.value.try_read()
     }
 
     /// Read the value. If the value has been dropped, this will panic.
     #[track_caller]
-    pub fn read(&self) -> S::Ref {
+    pub fn read(&self) -> S::Ref<T> {
         self.value.read()
     }
 
     /// Try to write the value. If the value has been dropped, this will return None.
     #[track_caller]
-    pub fn try_write(&mut self) -> Result<S::Mut, generational_box::BorrowMutError> {
+    pub fn try_write(&mut self) -> Result<S::Mut<T>, generational_box::BorrowMutError> {
         self.value.try_write()
     }
 
@@ -162,13 +162,13 @@ impl<T: 'static, S: Storage<T>> CopyValue<T, S> {
     ///
     /// Note: This is completely safe because the value is stored in a generational box. The lifetime that normally is passed to the returned reference is only used as a hint to user to prevent runtime overlapping borrow panics.
     #[track_caller]
-    pub fn write_unchecked(&self) -> S::Mut {
+    pub fn write_unchecked(&self) -> S::Mut<T> {
         self.value.write()
     }
 
     /// Write the value. If the value has been dropped, this will panic.
     #[track_caller]
-    pub fn write(&self) -> S::Mut {
+    pub fn write(&self) -> S::Mut<T> {
         self.value.write()
     }
 

+ 20 - 50
packages/signals/src/signal.rs

@@ -15,9 +15,7 @@ use dioxus_core::{
     },
     ScopeId,
 };
-use generational_box::{
-    GenerationalBoxId, Mappable, MappableMut, Storage, SyncStorage, UnsyncStorage,
-};
+use generational_box::{GenerationalBoxId, Storage, SyncStorage, UnsyncStorage};
 use parking_lot::RwLock;
 
 use crate::{get_effect_ref, CopyValue, EffectStackRef, EFFECT_STACK};
@@ -358,9 +356,7 @@ impl<T: 'static, S: Storage<SignalData<T>>> Signal<T, S> {
     ///
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn read(
-        &self,
-    ) -> <<S as Storage<SignalData<T>>>::Ref as Mappable<SignalData<T>>>::Mapped<T> {
+    pub fn read(&self) -> S::Ref<T> {
         let inner = self.inner.read();
         if let Some(effect) = EFFECT_STACK.with(|stack| stack.current()) {
             let subscribers = inner.subscribers.read();
@@ -387,27 +383,22 @@ impl<T: 'static, S: Storage<SignalData<T>>> Signal<T, S> {
                 }
             }
         }
-        S::Ref::map(inner, |v| &v.value)
+        S::map(inner, |v| &v.value)
     }
 
     /// Get the current value of the signal. **Unlike read, this will not subscribe the current scope to the signal which can cause parts of your UI to not update.**
     ///
     /// If the signal has been dropped, this will panic.
-    pub fn peek(
-        &self,
-    ) -> <<S as Storage<SignalData<T>>>::Ref as Mappable<SignalData<T>>>::Mapped<T> {
+    pub fn peek(&self) -> S::Ref<T> {
         let inner = self.inner.read();
-        S::Ref::map(inner, |v| &v.value)
+        S::map(inner, |v| &v.value)
     }
 
     /// Get a mutable reference to the signal's value.
     ///
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn write<'a>(
-        &'a mut self,
-    ) -> Write<T, <<S as Storage<SignalData<T>>>::Mut as MappableMut<SignalData<T>>>::Mapped<T>, S>
-    {
+    pub fn write<'a>(&'a mut self) -> Write<T, S> {
         self.write_unchecked()
     }
 
@@ -415,12 +406,9 @@ impl<T: 'static, S: Storage<SignalData<T>>> Signal<T, S> {
     ///
     /// This is public since it's useful in many scenarios, but we generally recommend mutation through [`Self::write`] instead.
     #[track_caller]
-    pub fn write_unchecked(
-        &self,
-    ) -> Write<T, <<S as Storage<SignalData<T>>>::Mut as MappableMut<SignalData<T>>>::Mapped<T>, S>
-    {
+    pub fn write_unchecked(&self) -> Write<T, S> {
         let inner = self.inner.write();
-        let borrow = S::Mut::map(inner, |v| &mut v.value);
+        let borrow = S::map_mut(inner, |v| &mut v.value);
         Write {
             write: borrow,
             signal: SignalSubscriberDrop { signal: *self },
@@ -489,14 +477,7 @@ impl<T: 'static, S: Storage<SignalData<T>>> Signal<T, S> {
     }
 
     /// Map the signal to a new type.
-    pub fn map<O>(
-        self,
-        f: impl Fn(&T) -> &O + 'static,
-    ) -> MappedSignal<
-        <<<S as generational_box::Storage<SignalData<T>>>::Ref as generational_box::Mappable<
-            SignalData<T>,
-        >>::Mapped<T> as generational_box::Mappable<T>>::Mapped<O>,
-    > {
+    pub fn map<O>(self, f: impl Fn(&T) -> &O + 'static) -> MappedSignal<S::Ref<O>> {
         MappedSignal::new(self, f)
     }
 
@@ -589,23 +570,18 @@ impl<T: 'static, S: Storage<SignalData<T>>> Drop for SignalSubscriberDrop<T, S>
 /// B is the dynamically checked type of the write (RefMut)
 /// S is the storage type of the signal
 /// I is the type of the original signal
-pub struct Write<
-    T: 'static,
-    B: MappableMut<T>,
-    S: Storage<SignalData<I>> = UnsyncStorage,
-    I: 'static = T,
-> {
-    write: B,
+pub struct Write<T: 'static, S: Storage<SignalData<I>> = UnsyncStorage, I: 'static = T> {
+    write: S::Mut<T>,
     signal: SignalSubscriberDrop<I, S>,
     phantom: std::marker::PhantomData<T>,
 }
 
-impl<T: 'static, B: MappableMut<T>, S: Storage<SignalData<I>>, I: 'static> Write<T, B, S, I> {
+impl<T: 'static, S: Storage<SignalData<I>>, I: 'static> Write<T, S, I> {
     /// Map the mutable reference to the signal's value to a new type.
-    pub fn map<O>(myself: Self, f: impl FnOnce(&mut T) -> &mut O) -> Write<O, B::Mapped<O>, S, I> {
+    pub fn map<O>(myself: Self, f: impl FnOnce(&mut T) -> &mut O) -> Write<O, S, I> {
         let Self { write, signal, .. } = myself;
         Write {
-            write: B::map(write, f),
+            write: S::map_mut(write, f),
             signal,
             phantom: std::marker::PhantomData,
         }
@@ -615,9 +591,9 @@ impl<T: 'static, B: MappableMut<T>, S: Storage<SignalData<I>>, I: 'static> Write
     pub fn filter_map<O>(
         myself: Self,
         f: impl FnOnce(&mut T) -> Option<&mut O>,
-    ) -> Option<Write<O, B::Mapped<O>, S, I>> {
+    ) -> Option<Write<O, S, I>> {
         let Self { write, signal, .. } = myself;
-        let write = B::try_map(write, f);
+        let write = S::try_map_mut(write, f);
         write.map(|write| Write {
             write,
             signal,
@@ -626,9 +602,7 @@ impl<T: 'static, B: MappableMut<T>, S: Storage<SignalData<I>>, I: 'static> Write
     }
 }
 
-impl<T: 'static, B: MappableMut<T>, S: Storage<SignalData<I>>, I: 'static> Deref
-    for Write<T, B, S, I>
-{
+impl<T: 'static, S: Storage<SignalData<I>>, I: 'static> Deref for Write<T, S, I> {
     type Target = T;
 
     fn deref(&self) -> &Self::Target {
@@ -636,7 +610,7 @@ impl<T: 'static, B: MappableMut<T>, S: Storage<SignalData<I>>, I: 'static> Deref
     }
 }
 
-impl<T, B: MappableMut<T>, S: Storage<SignalData<I>>, I> DerefMut for Write<T, B, S, I> {
+impl<T, S: Storage<SignalData<I>>, I> DerefMut for Write<T, S, I> {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.write
     }
@@ -677,18 +651,14 @@ impl<T: 'static, S: Storage<SignalData<T>>> ReadOnlySignal<T, S> {
     ///
     /// If the signal has been dropped, this will panic.
     #[track_caller]
-    pub fn read(
-        &self,
-    ) -> <<S as Storage<SignalData<T>>>::Ref as Mappable<SignalData<T>>>::Mapped<T> {
+    pub fn read(&self) -> S::Ref<T> {
         self.inner.read()
     }
 
     /// Get the current value of the signal. **Unlike read, this will not subscribe the current scope to the signal which can cause parts of your UI to not update.**
     ///
     /// If the signal has been dropped, this will panic.
-    pub fn peek(
-        &self,
-    ) -> <<S as Storage<SignalData<T>>>::Ref as Mappable<SignalData<T>>>::Mapped<T> {
+    pub fn peek(&self) -> S::Ref<T> {
         self.inner.peek()
     }