veecle_os_runtime/datastore/
initialized_reader.rs1use core::cell::Ref;
2use core::marker::PhantomData;
3
4use crate::datastore::{Storable, slot};
5
6#[derive(Debug)]
52pub struct InitializedReader<'a, T>
53where
54 T: Storable + 'static,
55{
56 waiter: slot::Waiter<'a, T>,
57
58 marker: PhantomData<fn(T)>,
59}
60
61impl<T> InitializedReader<'_, T>
62where
63 T: Storable + 'static,
64{
65 #[cfg_attr(feature = "veecle-telemetry", veecle_telemetry::instrument)]
71 pub fn read<U>(&self, f: impl FnOnce(&T::DataType) -> U) -> U {
72 self.waiter.read(|value| {
73 let value = value
74 .as_ref()
75 .expect("initialized reader should only access initialized values");
76
77 #[cfg(feature = "veecle-telemetry")]
79 veecle_telemetry::trace!("Slot read.", type_name = self.waiter.inner_type_name());
80 f(value)
81 })
82 }
83
84 pub fn read_cloned(&self) -> T::DataType
89 where
90 T::DataType: Clone,
91 {
92 self.read(|t| t.clone())
93 }
94
95 #[cfg_attr(feature = "veecle-telemetry", veecle_telemetry::instrument)]
103 pub async fn wait_for_update(&mut self) -> &mut Self {
104 self.waiter.wait().await;
105 self.waiter.update_generation();
106 self
107 }
108}
109
110impl<'a, T> InitializedReader<'a, T>
111where
112 T: Storable + 'static,
113{
114 pub(crate) fn new(waiter: slot::Waiter<'a, T>) -> Self {
116 Self {
117 waiter,
118 marker: Default::default(),
119 }
120 }
121}
122
123impl<T> super::combined_readers::Sealed for InitializedReader<'_, T> where T: Storable {}
124
125impl<T> super::combined_readers::CombinableReader for InitializedReader<'_, T>
126where
127 T: Storable,
128{
129 type ToBeRead = T::DataType;
130
131 fn borrow(&self) -> Ref<'_, Self::ToBeRead> {
132 Ref::map(self.waiter.borrow(), |t| t.as_ref().unwrap())
133 }
134
135 async fn wait_for_update(&mut self) {
136 self.wait_for_update().await;
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use core::pin::pin;
143 use futures::FutureExt;
144
145 use crate::datastore::{Reader, Slot, Storable, Writer, generational};
146
147 #[test]
148 fn read() {
149 #[derive(Eq, PartialEq, Debug, Clone, Storable)]
150 #[storable(crate = crate)]
151 struct Sensor(u8);
152
153 let source = pin!(generational::Source::new());
154 let slot = pin!(Slot::<Sensor>::new());
155
156 let mut writer = Writer::new(source.as_ref().waiter(), slot.as_ref());
157 let reader = Reader::from_slot(slot.as_ref());
158
159 assert!(reader.wait_init().now_or_never().is_none());
160
161 source.as_ref().increment_generation();
162 writer.write(Sensor(5)).now_or_never().unwrap();
163
164 let reader = Reader::from_slot(slot.as_ref())
165 .wait_init()
166 .now_or_never()
167 .unwrap();
168
169 assert_eq!(reader.read(|x: &Sensor| x.clone()), Sensor(5));
170 assert_eq!(reader.read_cloned(), Sensor(5));
171 }
172
173 #[test]
174 fn wait_for_update() {
175 #[derive(Eq, PartialEq, Debug, Clone, Storable)]
176 #[storable(crate = crate)]
177 struct Sensor(u8);
178
179 let source = pin!(generational::Source::new());
180 let slot = pin!(Slot::<Sensor>::new());
181
182 let mut writer = Writer::new(source.as_ref().waiter(), slot.as_ref());
183 let reader = Reader::from_slot(slot.as_ref());
184
185 source.as_ref().increment_generation();
186 writer.write(Sensor(1)).now_or_never().unwrap();
187
188 let mut reader = reader.wait_init().now_or_never().unwrap();
189
190 assert!(reader.wait_for_update().now_or_never().is_some());
191 assert!(reader.wait_for_update().now_or_never().is_none());
192
193 source.as_ref().increment_generation();
194 writer.write(Sensor(1)).now_or_never().unwrap();
195
196 reader
197 .wait_for_update()
198 .now_or_never()
199 .unwrap()
200 .read(|x| assert_eq!(x, &Sensor(1)));
201 }
202
203 #[test]
204 fn wait_init_wait_for_update() {
205 #[derive(Eq, PartialEq, Debug, Clone, Storable)]
206 #[storable(crate = crate)]
207 struct Sensor(u8);
208
209 let source = pin!(generational::Source::new());
210 let slot = pin!(Slot::<Sensor>::new());
211
212 let mut writer = Writer::new(source.as_ref().waiter(), slot.as_ref());
213 let reader = Reader::from_slot(slot.as_ref());
214
215 let mut wait_init_fut = pin!(reader.wait_init());
216 assert!(wait_init_fut.as_mut().now_or_never().is_none());
217 source.as_ref().increment_generation();
219 writer.write(Sensor(1)).now_or_never().unwrap();
220
221 let mut reader = wait_init_fut.now_or_never().unwrap();
222
223 reader
225 .wait_for_update()
226 .now_or_never()
227 .unwrap()
228 .read(|x| assert_eq!(x, &Sensor(1)));
229 }
230}