mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
feat: type-erased store Field structs
This commit is contained in:
parent
c72c2f4803
commit
0a89f151be
9 changed files with 433 additions and 103 deletions
|
@ -1,6 +1,7 @@
|
|||
use leptos::logging::log;
|
||||
use leptos::prelude::*;
|
||||
use reactive_stores::{
|
||||
AtIndex, Store, StoreField, StoreFieldIterator, Subfield,
|
||||
AtIndex, Field, Store, StoreField, StoreFieldIterator, Subfield,
|
||||
};
|
||||
use reactive_stores_macro::Store;
|
||||
|
||||
|
@ -60,6 +61,10 @@ pub fn App() -> impl IntoView {
|
|||
.collect_view()
|
||||
};
|
||||
|
||||
Effect::new(move |_| {
|
||||
log!("{:?}", *store.read());
|
||||
});
|
||||
|
||||
view! {
|
||||
<form on:submit=move |ev| {
|
||||
ev.prevent_default();
|
||||
|
@ -77,8 +82,7 @@ pub fn App() -> impl IntoView {
|
|||
fn TodoRow(
|
||||
store: Store<Todos>,
|
||||
idx: usize,
|
||||
// to be fair, this is gross
|
||||
todo: AtIndex<Subfield<Store<Todos>, Todos, Vec<Todo>>, Vec<Todo>>,
|
||||
#[prop(into)] todo: Field<Todo>,
|
||||
) -> impl IntoView {
|
||||
let completed = todo.completed();
|
||||
let title = todo.label();
|
||||
|
|
|
@ -431,6 +431,81 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub struct MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Deref,
|
||||
{
|
||||
inner: Inner,
|
||||
map_fn: Arc<dyn Fn(&Inner::Target) -> &U>,
|
||||
}
|
||||
|
||||
impl<Inner, U> Clone for MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Clone + Deref,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
map_fn: self.map_fn.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, U> Debug for MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Debug + Deref,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("MappedArc")
|
||||
.field("inner", &self.inner)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, U> MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Deref,
|
||||
{
|
||||
pub fn new(
|
||||
inner: Inner,
|
||||
map_fn: impl Fn(&Inner::Target) -> &U + 'static,
|
||||
) -> Self {
|
||||
Self {
|
||||
inner,
|
||||
map_fn: Arc::new(map_fn),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, U> Deref for MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Deref,
|
||||
{
|
||||
type Target = U;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
(self.map_fn)(self.inner.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, U: PartialEq> PartialEq for MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Deref,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
**self == **other
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, U: Display> Display for MappedArc<Inner, U>
|
||||
where
|
||||
Inner: Deref,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Display::fmt(&**self, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MappedMutArc<Inner, U>
|
||||
where
|
||||
Inner: Deref,
|
||||
|
|
196
reactive_stores/src/arc_field.rs
Normal file
196
reactive_stores/src/arc_field.rs
Normal file
|
@ -0,0 +1,196 @@
|
|||
use crate::{
|
||||
path::{StorePath, StorePathSegment},
|
||||
AtIndex, StoreField, Subfield,
|
||||
};
|
||||
use reactive_graph::{
|
||||
signal::ArcTrigger,
|
||||
traits::{
|
||||
DefinedAt, IsDisposed, ReadUntracked, Track, Trigger, UntrackableGuard,
|
||||
},
|
||||
};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut, IndexMut},
|
||||
panic::Location,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
pub struct ArcField<T>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: &'static Location<'static>,
|
||||
trigger: ArcTrigger,
|
||||
path: StorePath,
|
||||
read: Arc<dyn Fn() -> Option<StoreFieldReader<T>> + Send + Sync>,
|
||||
write: Arc<dyn Fn() -> Option<StoreFieldWriter<T>> + Send + Sync>,
|
||||
}
|
||||
|
||||
pub struct StoreFieldReader<T>(Box<dyn Deref<Target = T>>);
|
||||
|
||||
impl<T> StoreFieldReader<T> {
|
||||
pub fn new(inner: impl Deref<Target = T> + 'static) -> Self {
|
||||
Self(Box::new(inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for StoreFieldReader<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StoreFieldWriter<T>(Box<dyn UntrackableGuard<Target = T>>);
|
||||
|
||||
impl<T> StoreFieldWriter<T> {
|
||||
pub fn new(inner: impl UntrackableGuard<Target = T> + 'static) -> Self {
|
||||
Self(Box::new(inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for StoreFieldWriter<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for StoreFieldWriter<T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.0.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> UntrackableGuard for StoreFieldWriter<T> {
|
||||
fn untrack(&mut self) {
|
||||
self.0.untrack();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> StoreField<T> for ArcField<T> {
|
||||
type Reader = StoreFieldReader<T>;
|
||||
type Writer = StoreFieldWriter<T>;
|
||||
|
||||
fn get_trigger(&self, _path: StorePath) -> ArcTrigger {
|
||||
self.trigger.clone()
|
||||
}
|
||||
|
||||
fn path(&self) -> impl IntoIterator<Item = StorePathSegment> {
|
||||
std::iter::empty() // TODO
|
||||
}
|
||||
|
||||
fn reader(&self) -> Option<Self::Reader> {
|
||||
(self.read)().map(StoreFieldReader::new)
|
||||
}
|
||||
|
||||
fn writer(&self) -> Option<Self::Writer> {
|
||||
(self.write)().map(StoreFieldWriter::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, Prev, T> From<Subfield<Inner, Prev, T>> for ArcField<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
Subfield<Inner, Prev, T>: Clone,
|
||||
Inner: StoreField<Prev> + Send + Sync + 'static,
|
||||
Prev: 'static,
|
||||
{
|
||||
#[track_caller]
|
||||
fn from(value: Subfield<Inner, Prev, T>) -> Self {
|
||||
ArcField {
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
path: value.path().into_iter().collect(),
|
||||
trigger: value.get_trigger(value.path().into_iter().collect()),
|
||||
read: Arc::new({
|
||||
let value = value.clone();
|
||||
move || value.reader().map(StoreFieldReader::new)
|
||||
}),
|
||||
write: Arc::new({
|
||||
let value = value.clone();
|
||||
move || value.writer().map(StoreFieldWriter::new)
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, Prev> From<AtIndex<Inner, Prev>> for ArcField<Prev::Output>
|
||||
where
|
||||
AtIndex<Inner, Prev>: Clone,
|
||||
Inner: StoreField<Prev> + Send + Sync + 'static,
|
||||
Prev: IndexMut<usize> + Send + Sync + 'static,
|
||||
Prev::Output: Sized + Send + Sync,
|
||||
{
|
||||
#[track_caller]
|
||||
fn from(value: AtIndex<Inner, Prev>) -> Self {
|
||||
ArcField {
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
path: value.path().into_iter().collect(),
|
||||
trigger: value.get_trigger(value.path().into_iter().collect()),
|
||||
read: Arc::new({
|
||||
let value = value.clone();
|
||||
move || value.reader().map(StoreFieldReader::new)
|
||||
}),
|
||||
write: Arc::new({
|
||||
let value = value.clone();
|
||||
move || value.writer().map(StoreFieldWriter::new)
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for ArcField<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: self.defined_at,
|
||||
path: self.path.clone(),
|
||||
trigger: self.trigger.clone(),
|
||||
read: Arc::clone(&self.read),
|
||||
write: Arc::clone(&self.write),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DefinedAt for ArcField<T> {
|
||||
fn defined_at(&self) -> Option<&'static Location<'static>> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Some(self.defined_at)
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Trigger for ArcField<T> {
|
||||
fn trigger(&self) {
|
||||
self.trigger.trigger();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Track for ArcField<T> {
|
||||
fn track(&self) {
|
||||
self.trigger.track();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ReadUntracked for ArcField<T> {
|
||||
type Value = StoreFieldReader<T>;
|
||||
|
||||
fn try_read_untracked(&self) -> Option<Self::Value> {
|
||||
(self.read)()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IsDisposed for ArcField<T> {
|
||||
fn is_disposed(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
141
reactive_stores/src/field.rs
Normal file
141
reactive_stores/src/field.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use crate::{
|
||||
arc_field::{StoreFieldReader, StoreFieldWriter},
|
||||
path::{StorePath, StorePathSegment},
|
||||
ArcField, AtIndex, StoreField, Subfield,
|
||||
};
|
||||
use reactive_graph::{
|
||||
owner::StoredValue,
|
||||
signal::ArcTrigger,
|
||||
traits::{
|
||||
DefinedAt, IsDisposed, ReadUntracked, Track, Trigger, UntrackableGuard,
|
||||
},
|
||||
unwrap_signal,
|
||||
};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut, IndexMut},
|
||||
panic::Location,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
pub struct Field<T>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: &'static Location<'static>,
|
||||
inner: StoredValue<ArcField<T>>,
|
||||
}
|
||||
|
||||
impl<T> StoreField<T> for Field<T> {
|
||||
type Reader = StoreFieldReader<T>;
|
||||
type Writer = StoreFieldWriter<T>;
|
||||
|
||||
fn get_trigger(&self, path: StorePath) -> ArcTrigger {
|
||||
self.inner
|
||||
.try_get_value()
|
||||
.map(|inner| inner.get_trigger(path))
|
||||
.unwrap_or_else(unwrap_signal!(self))
|
||||
}
|
||||
|
||||
fn path(&self) -> impl IntoIterator<Item = StorePathSegment> {
|
||||
self.inner
|
||||
.try_get_value()
|
||||
.map(|inner| inner.path().into_iter().collect::<Vec<_>>())
|
||||
.unwrap_or_else(unwrap_signal!(self))
|
||||
}
|
||||
|
||||
fn reader(&self) -> Option<Self::Reader> {
|
||||
self.inner.try_get_value().and_then(|inner| inner.reader())
|
||||
}
|
||||
|
||||
fn writer(&self) -> Option<Self::Writer> {
|
||||
self.inner.try_get_value().and_then(|inner| inner.writer())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, Prev, T> From<Subfield<Inner, Prev, T>> for Field<T>
|
||||
where
|
||||
T: Send + Sync,
|
||||
Subfield<Inner, Prev, T>: Clone,
|
||||
Inner: StoreField<Prev> + Send + Sync + 'static,
|
||||
Prev: 'static,
|
||||
{
|
||||
#[track_caller]
|
||||
fn from(value: Subfield<Inner, Prev, T>) -> Self {
|
||||
Field {
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: StoredValue::new(value.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Inner, Prev> From<AtIndex<Inner, Prev>> for Field<Prev::Output>
|
||||
where
|
||||
AtIndex<Inner, Prev>: Clone,
|
||||
Inner: StoreField<Prev> + Send + Sync + 'static,
|
||||
Prev: IndexMut<usize> + Send + Sync + 'static,
|
||||
Prev::Output: Sized + Send + Sync,
|
||||
{
|
||||
#[track_caller]
|
||||
fn from(value: AtIndex<Inner, Prev>) -> Self {
|
||||
Field {
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: Location::caller(),
|
||||
inner: StoredValue::new(value.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for Field<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for Field<T> {}
|
||||
|
||||
impl<T> DefinedAt for Field<T> {
|
||||
fn defined_at(&self) -> Option<&'static Location<'static>> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Some(self.defined_at)
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Trigger for Field<T> {
|
||||
fn trigger(&self) {
|
||||
if let Some(inner) = self.inner.try_get_value() {
|
||||
inner.trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Track for Field<T> {
|
||||
fn track(&self) {
|
||||
if let Some(inner) = self.inner.try_get_value() {
|
||||
inner.track();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ReadUntracked for Field<T> {
|
||||
type Value = StoreFieldReader<T>;
|
||||
|
||||
fn try_read_untracked(&self) -> Option<Self::Value> {
|
||||
self.inner
|
||||
.try_get_value()
|
||||
.and_then(|inner| inner.try_read_untracked())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IsDisposed for Field<T> {
|
||||
fn is_disposed(&self) -> bool {
|
||||
!self.inner.exists()
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ use reactive_graph::{
|
|||
use std::{
|
||||
iter,
|
||||
marker::PhantomData,
|
||||
ops::{DerefMut, Index, IndexMut},
|
||||
ops::{DerefMut, IndexMut},
|
||||
panic::Location,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
@ -71,10 +71,9 @@ where
|
|||
impl<Inner, Prev> StoreField<Prev::Output> for AtIndex<Inner, Prev>
|
||||
where
|
||||
Inner: StoreField<Prev>,
|
||||
Prev: IndexMut<usize>,
|
||||
Prev: IndexMut<usize> + 'static,
|
||||
Prev::Output: Sized,
|
||||
{
|
||||
type Orig = Inner::Orig;
|
||||
type Reader = MappedMutArc<Inner::Reader, Prev::Output>;
|
||||
type Writer =
|
||||
MappedMutArc<WriteGuard<ArcTrigger, Inner::Writer>, Prev::Output>;
|
||||
|
@ -86,10 +85,6 @@ where
|
|||
.chain(iter::once(self.index.into()))
|
||||
}
|
||||
|
||||
fn data(&self) -> Arc<RwLock<Self::Orig>> {
|
||||
self.inner.data()
|
||||
}
|
||||
|
||||
fn get_trigger(&self, path: StorePath) -> ArcTrigger {
|
||||
self.inner.get_trigger(path)
|
||||
}
|
||||
|
@ -168,7 +163,7 @@ where
|
|||
impl<Inner, Prev> ReadUntracked for AtIndex<Inner, Prev>
|
||||
where
|
||||
Inner: StoreField<Prev>,
|
||||
Prev: IndexMut<usize>,
|
||||
Prev: IndexMut<usize> + 'static,
|
||||
Prev::Output: Sized,
|
||||
{
|
||||
type Value = <Self as StoreField<Prev::Output>>::Reader;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use reactive_graph::{
|
||||
owner::StoredValue,
|
||||
signal::{
|
||||
guards::{Mapped, Plain, ReadGuard},
|
||||
guards::{Plain, ReadGuard},
|
||||
ArcTrigger,
|
||||
},
|
||||
traits::{DefinedAt, IsDisposed, ReadUntracked, Track, Trigger},
|
||||
|
@ -13,12 +13,15 @@ use std::{
|
|||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
mod arc_field;
|
||||
mod field;
|
||||
mod iter;
|
||||
mod path;
|
||||
mod read_store_field;
|
||||
mod store_field;
|
||||
mod subfield;
|
||||
|
||||
pub use arc_field::ArcField;
|
||||
pub use field::Field;
|
||||
pub use iter::*;
|
||||
use path::StorePath;
|
||||
pub use store_field::StoreField;
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
use reactive_graph::{
|
||||
signal::{
|
||||
guards::{Mapped, Plain, ReadGuard},
|
||||
ArcTrigger,
|
||||
},
|
||||
traits::{DefinedAt, ReadUntracked, Track},
|
||||
};
|
||||
use std::{
|
||||
panic::Location,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
pub struct ArcReadStoreField<Orig, T>
|
||||
where
|
||||
T: 'static,
|
||||
{
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: &'static Location<'static>,
|
||||
data: Arc<RwLock<Orig>>,
|
||||
trigger: ArcTrigger,
|
||||
read: fn(&Orig) -> &T,
|
||||
}
|
||||
|
||||
impl<Orig, T> Clone for ArcReadStoreField<Orig, T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
#[cfg(debug_assertions)]
|
||||
defined_at: self.defined_at,
|
||||
data: Arc::clone(&self.data),
|
||||
trigger: self.trigger.clone(),
|
||||
read: self.read,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Orig, T> DefinedAt for ArcReadStoreField<Orig, T> {
|
||||
fn defined_at(&self) -> Option<&'static Location<'static>> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
Some(self.defined_at)
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Orig, T> Track for ArcReadStoreField<Orig, T> {
|
||||
fn track(&self) {
|
||||
self.trigger.track();
|
||||
}
|
||||
}
|
||||
|
||||
impl<Orig, T> ReadUntracked for ArcReadStoreField<Orig, T>
|
||||
where
|
||||
Orig: 'static,
|
||||
{
|
||||
type Value = ReadGuard<T, Mapped<Plain<Orig>, T>>;
|
||||
|
||||
fn try_read_untracked(&self) -> Option<Self::Value> {
|
||||
Mapped::try_new(Arc::clone(&self.data), self.read).map(ReadGuard::new)
|
||||
}
|
||||
}
|
|
@ -19,12 +19,9 @@ use std::{
|
|||
};
|
||||
|
||||
pub trait StoreField<T>: Sized {
|
||||
type Orig;
|
||||
type Reader: Deref<Target = T>;
|
||||
type Writer: UntrackableGuard<Target = T>;
|
||||
|
||||
fn data(&self) -> Arc<RwLock<Self::Orig>>;
|
||||
|
||||
fn get_trigger(&self, path: StorePath) -> ArcTrigger;
|
||||
|
||||
fn path(&self) -> impl IntoIterator<Item = StorePathSegment>;
|
||||
|
@ -38,14 +35,9 @@ impl<T> StoreField<T> for ArcStore<T>
|
|||
where
|
||||
T: 'static,
|
||||
{
|
||||
type Orig = T;
|
||||
type Reader = Plain<T>;
|
||||
type Writer = WriteGuard<ArcTrigger, ArcRwLockWriteGuardian<T>>;
|
||||
|
||||
fn data(&self) -> Arc<RwLock<Self::Orig>> {
|
||||
Arc::clone(&self.value)
|
||||
}
|
||||
|
||||
fn get_trigger(&self, path: StorePath) -> ArcTrigger {
|
||||
let triggers = &self.signals;
|
||||
let trigger = triggers.write().or_poisoned().get_or_insert(path);
|
||||
|
@ -72,17 +64,9 @@ impl<T> StoreField<T> for Store<T>
|
|||
where
|
||||
T: 'static,
|
||||
{
|
||||
type Orig = T;
|
||||
type Reader = Plain<T>;
|
||||
type Writer = WriteGuard<ArcTrigger, ArcRwLockWriteGuardian<T>>;
|
||||
|
||||
fn data(&self) -> Arc<RwLock<Self::Orig>> {
|
||||
self.inner
|
||||
.try_get_value()
|
||||
.map(|n| n.data())
|
||||
.unwrap_or_else(unwrap_signal!(self))
|
||||
}
|
||||
|
||||
fn get_trigger(&self, path: StorePath) -> ArcTrigger {
|
||||
self.inner
|
||||
.try_get_value()
|
||||
|
|
|
@ -4,10 +4,7 @@ use crate::{
|
|||
};
|
||||
use reactive_graph::{
|
||||
signal::{
|
||||
guards::{
|
||||
Mapped, MappedMut, Plain, ReadGuard, UntrackedWriteGuard,
|
||||
WriteGuard,
|
||||
},
|
||||
guards::{Mapped, MappedMut, WriteGuard},
|
||||
ArcTrigger,
|
||||
},
|
||||
traits::{
|
||||
|
@ -85,8 +82,8 @@ where
|
|||
impl<Inner, Prev, T> StoreField<T> for Subfield<Inner, Prev, T>
|
||||
where
|
||||
Inner: StoreField<Prev>,
|
||||
Prev: 'static,
|
||||
{
|
||||
type Orig = Inner::Orig;
|
||||
type Reader = Mapped<Inner::Reader, T>;
|
||||
type Writer = MappedMut<WriteGuard<ArcTrigger, Inner::Writer>, T>;
|
||||
|
||||
|
@ -97,10 +94,6 @@ where
|
|||
.chain(iter::once(self.path_segment))
|
||||
}
|
||||
|
||||
fn data(&self) -> Arc<RwLock<Self::Orig>> {
|
||||
self.inner.data()
|
||||
}
|
||||
|
||||
fn get_trigger(&self, path: StorePath) -> ArcTrigger {
|
||||
self.inner.get_trigger(path)
|
||||
}
|
||||
|
@ -145,6 +138,7 @@ where
|
|||
impl<Inner, Prev, T> Trigger for Subfield<Inner, Prev, T>
|
||||
where
|
||||
Inner: StoreField<Prev>,
|
||||
Prev: 'static,
|
||||
{
|
||||
fn trigger(&self) {
|
||||
let trigger = self.get_trigger(self.path().into_iter().collect());
|
||||
|
@ -154,7 +148,7 @@ where
|
|||
|
||||
impl<Inner, Prev, T> Track for Subfield<Inner, Prev, T>
|
||||
where
|
||||
Inner: StoreField<Prev> + Send + Sync + Clone + 'static,
|
||||
Inner: StoreField<Prev> + 'static,
|
||||
Prev: 'static,
|
||||
T: 'static,
|
||||
{
|
||||
|
@ -167,6 +161,7 @@ where
|
|||
impl<Inner, Prev, T> ReadUntracked for Subfield<Inner, Prev, T>
|
||||
where
|
||||
Inner: StoreField<Prev>,
|
||||
Prev: 'static,
|
||||
{
|
||||
type Value = <Self as StoreField<T>>::Reader;
|
||||
|
||||
|
@ -179,6 +174,7 @@ impl<Inner, Prev, T> Writeable for Subfield<Inner, Prev, T>
|
|||
where
|
||||
T: 'static,
|
||||
Inner: StoreField<Prev>,
|
||||
Prev: 'static,
|
||||
{
|
||||
type Value = T;
|
||||
|
||||
|
|
Loading…
Reference in a new issue