1use std::{
2 any::Any,
3 hash::{BuildHasher, Hash},
4 marker::PhantomData,
5 mem::ManuallyDrop,
6 pin::Pin,
7 task::Poll,
8};
9
10use anyhow::Result;
11use futures::Future;
12use pin_project_lite::pin_project;
13use rustc_hash::FxBuildHasher;
14
15use super::traits::VcValueType;
16use crate::{
17 MappedReadRef, ReadRawVcFuture, ReadRef, VcCast, VcValueTrait, VcValueTraitCast,
18 VcValueTypeCast, keyed::Keyed,
19};
20
21type VcReadTarget<T> = <<T as VcValueType>::Read as VcRead<T>>::Target;
22
23pub trait VcRead<T>
31where
32 T: VcValueType,
33{
34 type Target;
41
42 fn value_to_target_ref(value: &T) -> &Self::Target;
44
45 fn value_to_target(value: T) -> Self::Target;
47
48 fn target_to_value(target: Self::Target) -> T;
50
51 fn target_to_value_ref(target: &Self::Target) -> &T;
53
54 fn target_to_value_mut_ref(target: &mut Self::Target) -> &mut T;
56}
57
58pub struct VcDefaultRead<T> {
61 _phantom: PhantomData<T>,
62}
63
64impl<T> VcRead<T> for VcDefaultRead<T>
65where
66 T: VcValueType,
67{
68 type Target = T;
69
70 fn value_to_target_ref(value: &T) -> &Self::Target {
71 value
72 }
73
74 fn value_to_target(value: T) -> Self::Target {
75 value
76 }
77
78 fn target_to_value(target: Self::Target) -> T {
79 target
80 }
81
82 fn target_to_value_ref(target: &Self::Target) -> &T {
83 target
84 }
85
86 fn target_to_value_mut_ref(target: &mut Self::Target) -> &mut T {
87 target
88 }
89}
90
91pub struct VcTransparentRead<T, Target> {
94 _phantom: PhantomData<(T, Target)>,
95}
96
97impl<T, Target> VcRead<T> for VcTransparentRead<T, Target>
98where
99 T: VcValueType,
100 Target: Any + Send + Sync,
101{
102 type Target = Target;
103
104 fn value_to_target_ref(value: &T) -> &Self::Target {
105 unsafe {
111 std::mem::transmute_copy::<ManuallyDrop<&T>, &Self::Target>(&ManuallyDrop::new(value))
112 }
113 }
114
115 fn value_to_target(value: T) -> Self::Target {
116 unsafe {
118 std::mem::transmute_copy::<ManuallyDrop<T>, Self::Target>(&ManuallyDrop::new(value))
119 }
120 }
121
122 fn target_to_value(target: Self::Target) -> T {
123 unsafe {
125 std::mem::transmute_copy::<ManuallyDrop<Self::Target>, T>(&ManuallyDrop::new(target))
126 }
127 }
128
129 fn target_to_value_ref(target: &Self::Target) -> &T {
130 unsafe {
132 std::mem::transmute_copy::<ManuallyDrop<&Self::Target>, &T>(&ManuallyDrop::new(target))
133 }
134 }
135
136 fn target_to_value_mut_ref(target: &mut Self::Target) -> &mut T {
137 unsafe {
139 std::mem::transmute_copy::<ManuallyDrop<&mut Self::Target>, &mut T>(&ManuallyDrop::new(
140 target,
141 ))
142 }
143 }
144}
145
146pub struct ReadVcFuture<T, Cast = VcValueTypeCast<T>>
147where
148 T: ?Sized,
149 Cast: VcCast,
150{
151 raw: ReadRawVcFuture,
152 _phantom_t: PhantomData<T>,
153 _phantom_cast: PhantomData<Cast>,
154}
155
156impl<T, Cast> ReadVcFuture<T, Cast>
157where
158 T: ?Sized,
159 Cast: VcCast,
160{
161 pub fn strongly_consistent(mut self) -> Self {
163 self.raw = self.raw.strongly_consistent();
164 self
165 }
166
167 pub fn untracked(mut self) -> Self {
170 self.raw = self.raw.untracked();
171 self
172 }
173
174 pub fn final_read_hint(mut self) -> Self {
177 self.raw = self.raw.final_read_hint();
178 self
179 }
180}
181
182impl<T> ReadVcFuture<T, VcValueTypeCast<T>>
183where
184 T: VcValueType,
185 VcReadTarget<T>: Clone,
186{
187 pub fn owned(self) -> ReadOwnedVcFuture<T> {
189 ReadOwnedVcFuture { future: self }
190 }
191}
192
193impl<T> ReadVcFuture<T, VcValueTypeCast<T>>
194where
195 T: VcValueType,
196 VcReadTarget<T>: Keyed,
197 <VcReadTarget<T> as Keyed>::Key: Hash,
198{
199 pub fn get<'l>(mut self, key: &'l <VcReadTarget<T> as Keyed>::Key) -> ReadKeyedVcFuture<'l, T> {
202 self.raw = self.raw.track_with_key(FxBuildHasher.hash_one(key));
203 ReadKeyedVcFuture { future: self, key }
204 }
205
206 pub fn contains_key<'l>(
212 mut self,
213 key: &'l <VcReadTarget<T> as Keyed>::Key,
214 ) -> ReadContainsKeyedVcFuture<'l, T> {
215 self.raw = self.raw.track_with_key(FxBuildHasher.hash_one(key));
216 ReadContainsKeyedVcFuture { future: self, key }
217 }
218}
219
220impl<T> From<ReadRawVcFuture> for ReadVcFuture<T, VcValueTypeCast<T>>
221where
222 T: VcValueType,
223{
224 fn from(raw: ReadRawVcFuture) -> Self {
225 Self {
226 raw,
227 _phantom_t: PhantomData,
228 _phantom_cast: PhantomData,
229 }
230 }
231}
232
233impl<T> From<ReadRawVcFuture> for ReadVcFuture<T, VcValueTraitCast<T>>
234where
235 T: VcValueTrait + ?Sized,
236{
237 fn from(raw: ReadRawVcFuture) -> Self {
238 Self {
239 raw,
240 _phantom_t: PhantomData,
241 _phantom_cast: PhantomData,
242 }
243 }
244}
245
246impl<T, Cast> Future for ReadVcFuture<T, Cast>
247where
248 T: ?Sized,
249 Cast: VcCast,
250{
251 type Output = Result<Cast::Output>;
252
253 fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
254 let raw = unsafe { self.map_unchecked_mut(|this| &mut this.raw) };
256 Poll::Ready(std::task::ready!(raw.poll(cx)).and_then(Cast::cast))
257 }
258}
259
260pub struct ReadOwnedVcFuture<T>
261where
262 T: VcValueType,
263 VcReadTarget<T>: Clone,
264{
265 future: ReadVcFuture<T, VcValueTypeCast<T>>,
266}
267
268impl<T> Future for ReadOwnedVcFuture<T>
269where
270 T: VcValueType,
271 VcReadTarget<T>: Clone,
272{
273 type Output = Result<VcReadTarget<T>>;
274
275 fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
276 let future = unsafe { self.map_unchecked_mut(|this| &mut this.future) };
278 match future.poll(cx) {
279 Poll::Ready(Ok(result)) => Poll::Ready(Ok(ReadRef::into_owned(result))),
280 Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
281 Poll::Pending => Poll::Pending,
282 }
283 }
284}
285
286pin_project! {
287 pub struct ReadKeyedVcFuture<'l, T>
288 where
289 T: VcValueType,
290 VcReadTarget<T>: Keyed,
291 {
292 #[pin]
293 future: ReadVcFuture<T, VcValueTypeCast<T>>,
294 key: &'l <VcReadTarget<T> as Keyed>::Key,
295 }
296}
297
298impl<'l, T> Future for ReadKeyedVcFuture<'l, T>
299where
300 T: VcValueType,
301 VcReadTarget<T>: Keyed,
302{
303 type Output = Result<Option<MappedReadRef<T, <VcReadTarget<T> as Keyed>::Value>>>;
304
305 fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
306 let this = self.project();
308 match this.future.poll(cx) {
309 Poll::Ready(Ok(result)) => {
310 let mapped_read_ref = if let Some(value) = (*result).get(this.key) {
311 let ptr = value as *const _;
312 Some(unsafe { MappedReadRef::new(result.into_raw_arc(), ptr) })
313 } else {
314 None
315 };
316 Poll::Ready(Ok(mapped_read_ref))
317 }
318 Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
319 Poll::Pending => Poll::Pending,
320 }
321 }
322}
323
324pin_project! {
325 pub struct ReadContainsKeyedVcFuture<'l, T>
326 where
327 T: VcValueType,
328 VcReadTarget<T>: Keyed,
329 {
330 #[pin]
331 future: ReadVcFuture<T, VcValueTypeCast<T>>,
332 key: &'l <VcReadTarget<T> as Keyed>::Key,
333 }
334}
335
336impl<'l, T> Future for ReadContainsKeyedVcFuture<'l, T>
337where
338 T: VcValueType,
339 VcReadTarget<T>: Keyed,
340{
341 type Output = Result<bool>;
342
343 fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
344 let this = self.project();
346 match this.future.poll(cx) {
347 Poll::Ready(Ok(result)) => {
348 let result = (*result).contains_key(this.key);
349 Poll::Ready(Ok(result))
350 }
351 Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
352 Poll::Pending => Poll::Pending,
353 }
354 }
355}