1use std::{
2 any::Any,
3 fmt::Debug,
4 future::IntoFuture,
5 hash::{Hash, Hasher},
6 marker::PhantomData,
7 mem::transmute,
8 ops::Deref,
9};
10
11use anyhow::Result;
12use serde::{Deserialize, Serialize};
13
14use crate::{
15 RawVc, Upcast, UpcastStrict, VcRead, VcTransparentRead, VcValueTrait, VcValueType,
16 debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString},
17 trace::{TraceRawVcs, TraceRawVcsContext},
18 vc::Vc,
19};
20
21#[derive(Serialize, Deserialize)]
68#[serde(transparent, bound = "")]
69#[repr(transparent)]
70pub struct ResolvedVc<T>
71where
72 T: ?Sized,
73{
74 pub(crate) node: Vc<T>,
75}
76
77impl<T> ResolvedVc<T>
78where
79 T: ?Sized,
80{
81 #[deprecated(note = "No point in resolving a vc that is already resolved")]
85 pub async fn to_resolved(self) -> Result<Self> {
86 Ok(self)
87 }
88 #[deprecated(note = "No point in resolving a vc that is already resolved")]
89 pub async fn resolve(self) -> Result<Vc<T>> {
90 Ok(self.node)
91 }
92}
93
94impl<T> Copy for ResolvedVc<T> where T: ?Sized {}
95
96impl<T> Clone for ResolvedVc<T>
97where
98 T: ?Sized,
99{
100 fn clone(&self) -> Self {
101 *self
102 }
103}
104
105impl<T> Deref for ResolvedVc<T>
106where
107 T: ?Sized,
108{
109 type Target = Vc<T>;
110
111 fn deref(&self) -> &Self::Target {
112 &self.node
113 }
114}
115
116impl<T> PartialEq<ResolvedVc<T>> for ResolvedVc<T>
117where
118 T: ?Sized,
119{
120 fn eq(&self, other: &Self) -> bool {
121 self.node == other.node
122 }
123}
124
125impl<T> Eq for ResolvedVc<T> where T: ?Sized {}
126
127impl<T> Hash for ResolvedVc<T>
128where
129 T: ?Sized,
130{
131 fn hash<H: Hasher>(&self, state: &mut H) {
132 self.node.hash(state);
133 }
134}
135
136impl<T, Inner, Repr> Default for ResolvedVc<T>
137where
138 T: VcValueType<Read = VcTransparentRead<T, Inner, Repr>>,
139 Inner: Any + Send + Sync + Default,
140 Repr: VcValueType,
141{
142 fn default() -> Self {
143 Self::cell(Default::default())
144 }
145}
146
147macro_rules! into_future {
148 ($ty:ty) => {
149 impl<T> IntoFuture for $ty
150 where
151 T: VcValueType,
152 {
153 type Output = <Vc<T> as IntoFuture>::Output;
154 type IntoFuture = <Vc<T> as IntoFuture>::IntoFuture;
155 fn into_future(self) -> Self::IntoFuture {
156 (*self).into_future()
157 }
158 }
159 };
160}
161
162into_future!(ResolvedVc<T>);
163into_future!(&ResolvedVc<T>);
164into_future!(&mut ResolvedVc<T>);
165
166impl<T> ResolvedVc<T>
167where
168 T: VcValueType,
169{
170 #[doc(hidden)]
172 pub fn cell_private(inner: <T::Read as VcRead<T>>::Target) -> Self {
173 Self {
174 node: Vc::<T>::cell_private(inner),
175 }
176 }
177}
178
179impl<T, Inner, Repr> ResolvedVc<T>
180where
181 T: VcValueType<Read = VcTransparentRead<T, Inner, Repr>>,
182 Inner: Any + Send + Sync,
183 Repr: VcValueType,
184{
185 pub fn cell(inner: Inner) -> Self {
186 Self {
187 node: Vc::<T>::cell(inner),
188 }
189 }
190}
191
192impl<T> ResolvedVc<T>
193where
194 T: ?Sized,
195{
196 #[inline(always)]
200 pub fn upcast<K>(this: Self) -> ResolvedVc<K>
201 where
202 T: UpcastStrict<K>,
203 K: VcValueTrait + ?Sized,
204 {
205 Self::upcast_non_strict(this)
206 }
207
208 #[inline(always)]
214 pub fn upcast_non_strict<K>(this: Self) -> ResolvedVc<K>
215 where
216 T: Upcast<K>,
217 K: VcValueTrait + ?Sized,
218 {
219 ResolvedVc {
220 node: Vc::upcast_non_strict(this.node),
221 }
222 }
223
224 #[inline(always)]
228 pub fn upcast_vec<K>(vec: Vec<Self>) -> Vec<ResolvedVc<K>>
229 where
230 T: UpcastStrict<K>,
231 K: VcValueTrait + ?Sized,
232 {
233 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<ResolvedVc<K>>());
234 debug_assert!(size_of::<Vec<ResolvedVc<T>>>() == size_of::<Vec<ResolvedVc<K>>>());
235 let (ptr, len, capacity) = vec.into_raw_parts();
236 unsafe { Vec::from_raw_parts(ptr as *mut ResolvedVc<K>, len, capacity) }
238 }
239
240 pub fn deref_vec(vec: Vec<ResolvedVc<T>>) -> Vec<Vc<T>> {
242 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
243 unsafe { transmute::<Vec<ResolvedVc<T>>, Vec<Vc<T>>>(vec) }
245 }
246
247 pub fn deref_slice(slice: &[ResolvedVc<T>]) -> &[Vc<T>] {
249 debug_assert!(size_of::<ResolvedVc<T>>() == size_of::<Vc<T>>());
250 unsafe { transmute::<&[ResolvedVc<T>], &[Vc<T>]>(slice) }
252 }
253}
254
255impl<T> ResolvedVc<T>
256where
257 T: VcValueTrait + ?Sized,
258{
259 pub fn try_sidecast<K>(this: Self) -> Option<ResolvedVc<K>>
266 where
267 K: VcValueTrait + ?Sized,
268 {
269 debug_assert!(
273 <K as VcValueTrait>::get_trait_type_id() != <T as VcValueTrait>::get_trait_type_id(),
274 "Attempted to cast a type {} to itself, which is pointless. Use the value directly \
275 instead.",
276 crate::registry::get_trait(<T as VcValueTrait>::get_trait_type_id()).global_name
277 );
278 let raw_vc = this.node.node;
281 raw_vc
282 .resolved_has_trait(<K as VcValueTrait>::get_trait_type_id())
283 .then_some(ResolvedVc {
284 node: Vc {
285 node: raw_vc,
286 _t: PhantomData,
287 },
288 })
289 }
290
291 pub fn try_downcast<K>(this: Self) -> Option<ResolvedVc<K>>
298 where
299 K: UpcastStrict<T> + VcValueTrait + ?Sized,
300 {
301 Self::try_sidecast(this)
303 }
304
305 pub fn try_downcast_type<K>(this: Self) -> Option<ResolvedVc<K>>
311 where
312 K: UpcastStrict<T> + VcValueType,
313 {
314 let raw_vc = this.node.node;
315 raw_vc
316 .resolved_is_type(<K as VcValueType>::get_value_type_id())
317 .then_some(ResolvedVc {
318 node: Vc {
319 node: raw_vc,
320 _t: PhantomData,
321 },
322 })
323 }
324}
325
326impl<T> Debug for ResolvedVc<T>
333where
334 T: ?Sized,
335{
336 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
337 f.debug_tuple("ResolvedVc").field(&self.node.node).finish()
338 }
339}
340
341impl<T> TraceRawVcs for ResolvedVc<T>
342where
343 T: ?Sized,
344{
345 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
346 TraceRawVcs::trace_raw_vcs(&self.node, trace_context);
347 }
348}
349
350impl<T> ValueDebugFormat for ResolvedVc<T>
351where
352 T: UpcastStrict<Box<dyn ValueDebug>> + Send + Sync + ?Sized,
353{
354 fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString<'_> {
355 self.node.value_debug_format(depth)
356 }
357}
358
359impl<T> TryFrom<RawVc> for ResolvedVc<T>
360where
361 T: ?Sized,
362{
363 type Error = anyhow::Error;
364
365 fn try_from(raw: RawVc) -> Result<Self> {
366 if !matches!(raw, RawVc::TaskCell(..)) {
367 anyhow::bail!("Given RawVc {raw:?} is not a TaskCell");
368 }
369 Ok(Self {
370 node: Vc::from(raw),
371 })
372 }
373}