use std::{ hash::Hash, ops::{self, Index, IndexMut}, }; use crate::{store::Store, ReadStore}; use dioxus_signals::{ AnyStorage, BorrowError, BorrowMutError, ReadSignal, Readable, UnsyncStorage, Writable, WriteLock, WriteSignal, }; impl Store { /// Index into the store, returning a store that allows access to the item at the given index. The /// new store will only update when the item at the index changes. /// /// # Example /// ```rust, no_run /// use dioxus_stores::*; /// let store = use_store(|| vec![1, 2, 3]); /// let indexed_store = store.index(1); /// // The indexed store can access the store methods of the indexed store. /// assert_eq!(indexed_store(), 2); /// ``` pub fn index(self, index: Idx) -> Store> where T: IndexMut + 'static, Idx: Hash + 'static, Lens: Readable + 'static, { self.into_selector() .hash_child_unmapped(&index) .map_writer(move |write| IndexWrite { index, write }) .into() } } /// A specific index in a `Readable` / `Writable` type #[derive(Clone, Copy)] pub struct IndexWrite { index: Index, write: Write, } impl Readable for IndexWrite where Write: Readable, Write::Target: ops::Index + 'static, Index: Clone, { type Target = >::Output; type Storage = Write::Storage; fn try_read_unchecked(&self) -> Result, BorrowError> where Self::Target: 'static, { self.write.try_read_unchecked().map(|value| { Self::Storage::map(value, |value: &Write::Target| { value.index(self.index.clone()) }) }) } fn try_peek_unchecked(&self) -> Result, BorrowError> where Self::Target: 'static, { self.write.try_peek_unchecked().map(|value| { Self::Storage::map(value, |value: &Write::Target| { value.index(self.index.clone()) }) }) } fn subscribers(&self) -> dioxus_core::Subscribers where Self::Target: 'static, { self.write.subscribers() } } impl Writable for IndexWrite where Write: Writable, Write::Target: ops::IndexMut + 'static, Index: Clone, { type WriteMetadata = Write::WriteMetadata; fn try_write_unchecked( &self, ) -> Result, BorrowMutError> where Self::Target: 'static, { self.write.try_write_unchecked().map(|value| { WriteLock::map(value, |value: &mut Write::Target| { value.index_mut(self.index.clone()) }) }) } } impl ::std::convert::From>> for Store> where Write: Writable + 'static, Write::WriteMetadata: 'static, Write::Target: ops::IndexMut + 'static, Idx: Clone + 'static, T: 'static, { fn from(value: Store>) -> Self { value .into_selector() .map_writer(|writer| WriteSignal::new(writer)) .into() } } impl ::std::convert::From>> for ReadStore where Write: Readable + 'static, Write::Target: ops::Index + 'static, Idx: Clone + 'static, T: 'static, { fn from(value: Store>) -> Self { value .into_selector() .map_writer(|writer| ReadSignal::new(writer)) .into() } }