Skip to content

Commit

Permalink
feat(turbo-tasks): Add ResolvedVc versions of casting functions
Browse files Browse the repository at this point in the history
  • Loading branch information
bgw committed Sep 28, 2024
1 parent 34e6f48 commit b0e02bc
Showing 1 changed file with 74 additions and 1 deletion.
75 changes: 74 additions & 1 deletion turbopack/crates/turbo-tasks/src/vc/resolved.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use serde::{Deserialize, Serialize};
use crate::{
trace::{TraceRawVcs, TraceRawVcsContext},
vc::Vc,
RcStr, VcRead, VcTransparentRead, VcValueType,
RcStr, ResolveTypeError, Upcast, VcRead, VcTransparentRead, VcValueTrait, VcValueType,
};

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -122,6 +122,79 @@ where
}
}

impl<T> ResolvedVc<T>
where
T: ?Sized + Send,
{
/// Upcasts the given `ResolvedVc<T>` to a `ResolvedVc<Box<dyn K>>`.
///
/// See also: [`Vc::upcast`].
#[inline(always)]
pub fn upcast<K>(this: Self) -> ResolvedVc<K>
where
T: Upcast<K>,
K: VcValueTrait + ?Sized + Send,
{
ResolvedVc {
node: Vc::upcast(this.node),
}
}
}

impl<T> ResolvedVc<T>
where
T: VcValueTrait + ?Sized + Send,
{
/// Attempts to sidecast the given `Vc<Box<dyn T>>` to a `Vc<Box<dyn K>>`.
///
/// Returns `None` if the underlying value type does not implement `K`.
///
/// **Note:** if the trait `T` is required to implement `K`, use [`ResolvedVc::upcast`] instead.
/// This provides stronger guarantees, removing the need for a [`Result`] return type.
///
/// See also: [`Vc::try_resolve_sidecast`].
pub async fn try_sidecast<K>(this: Self) -> Result<Option<ResolvedVc<K>>, ResolveTypeError>
where
K: VcValueTrait + ?Sized + Send,
{
// must be async, as we must read the cell to determine the type
Ok(Vc::try_resolve_sidecast(this.node)
.await?
.map(|node| ResolvedVc { node }))
}

/// Attempts to downcast the given `ResolvedVc<Box<dyn T>>` to a `ResolvedVc<K>`, where `K`
/// is of the form `Box<dyn L>`, and `L` is a value trait.
///
/// Returns `None` if the underlying value type is not a `K`.
///
/// See also: [`Vc::try_resolve_downcast`].
pub async fn try_downcast<K>(this: Self) -> Result<Option<ResolvedVc<K>>, ResolveTypeError>
where
K: Upcast<T>,
K: VcValueTrait + ?Sized + Send,
{
Ok(Vc::try_resolve_downcast(this.node)
.await?
.map(|node| ResolvedVc { node }))
}

/// Attempts to downcast the given `Vc<Box<dyn T>>` to a `Vc<K>`, where `K` is a value type.
///
/// Returns `None` if the underlying value type is not a `K`.
///
/// See also: [`Vc::try_resolve_downcast_type`].
pub async fn try_downcast_type<K>(this: Self) -> Result<Option<ResolvedVc<K>>, ResolveTypeError>
where
K: Upcast<T>,
K: VcValueType,
{
Ok(Vc::try_resolve_downcast_type(this.node)
.await?
.map(|node| ResolvedVc { node }))
}
}

impl<T> std::fmt::Debug for ResolvedVc<T>
where
T: Send,
Expand Down

0 comments on commit b0e02bc

Please sign in to comment.