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 #[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 veecle_telemetry::trace!("Slot read", type_name = self.waiter.inner_type_name());
79 f(value)
80 })
81 }
82
83 pub fn read_cloned(&self) -> T::DataType
88 where
89 T::DataType: Clone,
90 {
91 self.read(|t| t.clone())
92 }
93
94 #[veecle_telemetry::instrument]
102 pub async fn wait_for_update(&mut self) -> &mut Self {
103 self.waiter.wait().await;
104 self.waiter.update_generation();
105 self
106 }
107}
108
109impl<'a, T> InitializedReader<'a, T>
110where
111 T: Storable + 'static,
112{
113 pub(crate) fn new(waiter: slot::Waiter<'a, T>) -> Self {
115 Self {
116 waiter,
117 marker: Default::default(),
118 }
119 }
120}
121
122impl<T> super::combined_readers::Sealed for InitializedReader<'_, T> where T: Storable {}
123
124impl<T> super::combined_readers::CombinableReader for InitializedReader<'_, T>
125where
126 T: Storable,
127{
128 type ToBeRead = T::DataType;
129
130 fn borrow(&self) -> Ref<'_, Self::ToBeRead> {
131 Ref::map(self.waiter.borrow(), |t| t.as_ref().unwrap())
132 }
133
134 async fn wait_for_update(&mut self) {
135 self.wait_for_update().await;
136 }
137}
138
139#[cfg(test)]
140#[cfg_attr(coverage_nightly, coverage(off))]
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}