Skip to main content

turbo_tasks/
value.rs

1use std::{fmt::Debug, marker::PhantomData, ops::Deref};
2
3use anyhow::Result;
4
5use crate::SharedReference;
6
7/// Pass a value by value (`Value<Xxx>`) instead of by reference (`Vc<Xxx>`).
8///
9/// Doesn't require serialization, and won't be stored in the filesystem cache
10/// in the future.
11#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
12pub struct TransientValue<T> {
13    inner: T,
14}
15
16impl<T> TransientValue<T> {
17    pub fn new(value: T) -> Self {
18        Self { inner: value }
19    }
20
21    pub fn into_value(self) -> T {
22        self.inner
23    }
24}
25
26impl<T> Deref for TransientValue<T> {
27    type Target = T;
28
29    fn deref(&self) -> &Self::Target {
30        &self.inner
31    }
32}
33
34/// Pass a reference to an instance to a turbo-tasks function.
35///
36/// Equality and hash is implemented as pointer comparison.
37///
38/// Doesn't require serialization, and won't be stored in the filesystem cache
39/// in the future, so we don't include the `ValueTypeId` in the
40/// `SharedReference`.
41pub struct TransientInstance<T> {
42    inner: SharedReference,
43    phantom: PhantomData<T>,
44}
45
46impl<T> Debug for TransientInstance<T> {
47    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48        f.debug_tuple("TransientInstance").finish()
49    }
50}
51
52impl<T> Clone for TransientInstance<T> {
53    fn clone(&self) -> Self {
54        Self {
55            inner: self.inner.clone(),
56            phantom: self.phantom,
57        }
58    }
59}
60
61impl<T> Eq for TransientInstance<T> {}
62
63impl<T> PartialEq for TransientInstance<T> {
64    fn eq(&self, other: &Self) -> bool {
65        self.inner == other.inner
66    }
67}
68
69impl<T> std::hash::Hash for TransientInstance<T> {
70    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
71        self.inner.hash(state);
72    }
73}
74
75impl<T: Send + Sync + 'static> From<TransientInstance<T>> for triomphe::Arc<T> {
76    fn from(instance: TransientInstance<T>) -> Self {
77        // we know this downcast must work because we have type T
78        instance.inner.downcast().unwrap()
79    }
80}
81
82impl<T: Send + Sync + 'static> From<TransientInstance<T>> for SharedReference {
83    fn from(instance: TransientInstance<T>) -> Self {
84        instance.inner
85    }
86}
87
88impl<T: Send + Sync + 'static> From<triomphe::Arc<T>> for TransientInstance<T> {
89    fn from(arc: triomphe::Arc<T>) -> Self {
90        Self {
91            inner: SharedReference::new(arc),
92            phantom: PhantomData,
93        }
94    }
95}
96
97impl<T: Send + Sync + 'static> TryFrom<SharedReference> for TransientInstance<T> {
98    type Error = ();
99
100    fn try_from(inner: SharedReference) -> Result<Self, Self::Error> {
101        if inner.0.downcast_ref::<T>().is_some() {
102            Ok(Self {
103                inner,
104                phantom: PhantomData,
105            })
106        } else {
107            Err(())
108        }
109    }
110}
111
112impl<T: Send + Sync + 'static> TransientInstance<T> {
113    pub fn new(value: T) -> Self {
114        Self {
115            inner: SharedReference::new(triomphe::Arc::new(value)),
116            phantom: PhantomData,
117        }
118    }
119}
120
121impl<T: 'static> Deref for TransientInstance<T> {
122    type Target = T;
123
124    fn deref(&self) -> &Self::Target {
125        self.inner.0.downcast_ref().unwrap()
126    }
127}