Traits
#[turbo_tasks::value_trait]
pub trait MyTrait {
fn method(self: Vc<Self>, a: i32) -> Vc<Something>;
// External signature: fn method(self: Vc<Self>, a: i32) -> Vc<Something>
async fn method2(&self, a: i32) -> Result<Vc<Something>> {
// Default implementation
}
}
#[turbo_tasks::value_impl]
pub trait OtherTrait: MyTrait + ValueToString {
// ...
}
#[turbo_tasks::value_trait]
annotation is required to define traits in Turbo-Engine.- All methods are Turbo-Engine functions.
self
argument is alwaysVc<Self>
.- Default implementation are supported and behave similar to defining Turbo-Engine functions.
Vc<Box<dyn MyTrait>>
is a Vc to a trait.
Implementing traits
#[turbo_tasks::value_impl]
impl MyTrait for Something {
fn method(self: Vc<Self>, a: i32) -> Vc<Something> {
// Implementation
}
fn method2(&self, a: i32) -> Vc<Something> {
// Implementation
}
}
Upcasting
Vcs can be upcasted to a trait Vc:
let something_vc: Vc<Something> = ...;
let trait_vc: Vc<Box<dyn MyTrait>> = Vc::upcast(something_vc);
Downcasting
Vcs can also be downcasted to a concrete type of a subtrait:
let trait_vc: Vc<Box<dyn MyTrait>> = ...;
if let Some(something_vc) = Vc::try_downcast_type::<Something>(trait_vc).await? {
// ...
}
let trait_vc: Vc<Box<dyn MyTrait>> = ...;
if let Some(something_vc) = Vc::try_downcast::<Box<dyn OtherTrait>>(trait_vc).await? {
// ...
}
There is a compile-time check that the source trait is implemented by the target trait/type.
Note: This will resolve the Vc and have similar implications as .resolve().await?
.
Sidecasting
let trait_vc: Vc<Box<dyn MyTrait>> = ...;
if let Some(something_vc) = Vc::try_sidecast::<Box<dyn UnrelatedTrait>>(trait_vc).await? {
// ...
}
This won't do any compile-time checks, so downcasting should be preferred if possible.
Note: This will resolve the Vc and have similar implications as .resolve().await?
.