dioxus_stores/impls/
slice.rs1use std::{iter::FusedIterator, panic::Location};
4
5use crate::{ReadStore, impls::index::IndexSelector, store::Store};
6use dioxus_signals::{
7 AnyStorage, BorrowError, BorrowMutError, ReadSignal, Readable, ReadableExt, UnsyncStorage,
8 Writable, WriteLock, WriteSignal,
9};
10use generational_box::ValueDroppedError;
11
12impl<Lens, I> Store<Vec<I>, Lens>
13where
14 Lens: Readable<Target = Vec<I>> + 'static,
15 I: 'static,
16{
17 pub fn len(&self) -> usize {
27 self.selector().track_shallow();
28 self.selector().peek().len()
29 }
30
31 pub fn is_empty(&self) -> bool {
41 self.selector().track_shallow();
42 self.selector().peek().is_empty()
43 }
44
45 #[track_caller]
56 pub fn iter(
57 &self,
58 ) -> impl ExactSizeIterator<Item = Store<I, VecGetWrite<Lens>>>
59 + DoubleEndedIterator
60 + FusedIterator
61 + '_
62 where
63 Lens: Clone,
64 {
65 let location = Location::caller();
66 (0..self.len()).map(move |i| self.clone().get_unchecked_at(i, location))
67 }
68
69 pub fn get(&self, index: usize) -> Option<Store<I, VecGetWrite<Lens>>>
82 where
83 Lens: Clone,
84 {
85 if index >= self.len() {
86 None
87 } else {
88 Some(self.clone().get_unchecked(index))
89 }
90 }
91
92 #[track_caller]
96 pub fn get_unchecked(self, index: usize) -> Store<I, VecGetWrite<Lens>> {
97 self.get_unchecked_at(index, Location::caller())
98 }
99
100 fn get_unchecked_at(
101 self,
102 index: usize,
103 location: &'static Location<'static>,
104 ) -> Store<I, VecGetWrite<Lens>> {
105 <Vec<I>>::scope_selector(self.into_selector(), &index)
106 .map_writer(move |write| VecGetWrite {
107 index,
108 write,
109 created: location,
110 })
111 .into()
112 }
113}
114
115#[derive(Clone, Copy)]
117pub struct VecGetWrite<Write> {
118 index: usize,
119 write: Write,
120 created: &'static Location<'static>,
121}
122
123impl<Write, T> Readable for VecGetWrite<Write>
124where
125 Write: Readable<Target = Vec<T>>,
126 T: 'static,
127{
128 type Target = T;
129 type Storage = Write::Storage;
130
131 fn try_read_unchecked(&self) -> Result<dioxus_signals::ReadableRef<'static, Self>, BorrowError>
132 where
133 Self::Target: 'static,
134 {
135 self.write.try_read_unchecked().and_then(|value| {
136 let index = self.index;
137 Self::Storage::try_map(value, move |value: &Vec<T>| value.get(index))
138 .ok_or_else(|| BorrowError::Dropped(ValueDroppedError::new(self.created)))
139 })
140 }
141
142 fn try_peek_unchecked(&self) -> Result<dioxus_signals::ReadableRef<'static, Self>, BorrowError>
143 where
144 Self::Target: 'static,
145 {
146 self.write.try_peek_unchecked().and_then(|value| {
147 let index = self.index;
148 Self::Storage::try_map(value, move |value: &Vec<T>| value.get(index))
149 .ok_or_else(|| BorrowError::Dropped(ValueDroppedError::new(self.created)))
150 })
151 }
152
153 fn subscribers(&self) -> dioxus_core::Subscribers
154 where
155 Self::Target: 'static,
156 {
157 self.write.subscribers()
158 }
159}
160
161impl<Write, T> Writable for VecGetWrite<Write>
162where
163 Write: Writable<Target = Vec<T>>,
164 T: 'static,
165{
166 type WriteMetadata = Write::WriteMetadata;
167
168 fn try_write_unchecked(
169 &self,
170 ) -> Result<dioxus_signals::WritableRef<'static, Self>, BorrowMutError>
171 where
172 Self::Target: 'static,
173 {
174 self.write.try_write_unchecked().and_then(|value| {
175 let index = self.index;
176 WriteLock::filter_map(value, move |value: &mut Vec<T>| value.get_mut(index))
177 .ok_or_else(|| BorrowMutError::Dropped(ValueDroppedError::new(self.created)))
178 })
179 }
180}
181
182impl<T, Write> ::std::convert::From<Store<T, VecGetWrite<Write>>> for Store<T, WriteSignal<T>>
183where
184 Write: Writable<Target = Vec<T>, Storage = UnsyncStorage> + 'static,
185 Write::WriteMetadata: 'static,
186 T: 'static,
187{
188 fn from(value: Store<T, VecGetWrite<Write>>) -> Self {
189 value
190 .into_selector()
191 .map_writer(|writer| WriteSignal::new(writer))
192 .into()
193 }
194}
195
196impl<T, Write> ::std::convert::From<Store<T, VecGetWrite<Write>>> for ReadStore<T>
197where
198 Write: Readable<Target = Vec<T>, Storage = UnsyncStorage> + 'static,
199 T: 'static,
200{
201 fn from(value: Store<T, VecGetWrite<Write>>) -> Self {
202 value
203 .into_selector()
204 .map_writer(|writer| ReadSignal::new(writer))
205 .into()
206 }
207}