turbo_tasks/vc/
cast.rs

1use std::marker::PhantomData;
2
3use anyhow::Result;
4
5use crate::{ReadRef, TraitRef, VcValueTrait, VcValueType, backend::TypedCellContent};
6
7/// Trait defined to share behavior between values and traits within
8/// [`ReadRawVcFuture`][crate::ReadRawVcFuture]. See [`VcValueTypeCast`] and
9/// [`VcValueTraitCast`].
10///
11/// This trait is sealed and cannot be implemented by users.
12pub trait VcCast: private::Sealed {
13    type Output;
14
15    fn cast(content: TypedCellContent) -> Result<Self::Output>;
16}
17
18/// Casts an arbitrary cell content into a [`ReadRef<T>`].
19pub struct VcValueTypeCast<T> {
20    _phantom: PhantomData<T>,
21}
22
23impl<T> VcCast for VcValueTypeCast<T>
24where
25    T: VcValueType,
26{
27    type Output = ReadRef<T>;
28
29    fn cast(content: TypedCellContent) -> Result<Self::Output> {
30        content.cast()
31    }
32}
33
34/// Casts an arbitrary cell content into a [`TraitRef<T>`].
35pub struct VcValueTraitCast<T>
36where
37    T: ?Sized,
38{
39    _phantom: PhantomData<T>,
40}
41
42impl<T> VcCast for VcValueTraitCast<T>
43where
44    T: VcValueTrait + ?Sized,
45{
46    type Output = TraitRef<T>;
47
48    fn cast(content: TypedCellContent) -> Result<Self::Output> {
49        // Safety: Constructor ensures the cell content points to a value that
50        // implements T
51        content.cast_trait::<T>()
52    }
53}
54
55// Implement the sealed trait pattern for `VcCast`.
56// https://rust-lang.github.io/api-guidelines/future-proofing.html
57mod private {
58    use super::{VcValueTraitCast, VcValueTypeCast};
59    use crate::{VcValueTrait, VcValueType};
60
61    pub trait Sealed {}
62    impl<T> Sealed for VcValueTypeCast<T> where T: VcValueType {}
63    impl<T> Sealed for VcValueTraitCast<T> where T: VcValueTrait + ?Sized {}
64}