1use std::{fmt::Debug, future::Future, marker::PhantomData};
2
3use anyhow::Result;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 Vc, VcValueTrait,
8 registry::get_value_type,
9 task::shared_reference::TypedSharedReference,
10 vc::{ReadVcFuture, VcValueTraitCast, cast::VcCast},
11};
12
13pub struct TraitRef<T>
22where
23 T: ?Sized,
24{
25 shared_reference: TypedSharedReference,
26 _t: PhantomData<T>,
27}
28
29impl<T> Debug for TraitRef<T> {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("TraitRef")
32 .field("shared_reference", &self.shared_reference)
33 .finish()
34 }
35}
36
37impl<T> Clone for TraitRef<T> {
38 fn clone(&self) -> Self {
39 Self {
40 shared_reference: self.shared_reference.clone(),
41 _t: PhantomData,
42 }
43 }
44}
45
46impl<T> PartialEq for TraitRef<T> {
47 fn eq(&self, other: &Self) -> bool {
48 self.shared_reference == other.shared_reference
49 }
50}
51
52impl<T> Eq for TraitRef<T> {}
53
54impl<T> std::hash::Hash for TraitRef<T> {
55 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
56 self.shared_reference.hash(state)
57 }
58}
59
60impl<T> Serialize for TraitRef<T> {
61 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
62 self.shared_reference.serialize(serializer)
63 }
64}
65
66impl<'de, T> Deserialize<'de> for TraitRef<T> {
67 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
68 Ok(Self {
69 shared_reference: TypedSharedReference::deserialize(deserializer)?,
70 _t: PhantomData,
71 })
72 }
73}
74
75unsafe impl<T> Sync for TraitRef<T> where T: ?Sized {}
78
79unsafe impl<T> Send for TraitRef<T> where T: ?Sized {}
82
83impl<T> Unpin for TraitRef<T> where T: ?Sized {}
84
85impl<T> TraitRef<T>
86where
87 T: ?Sized,
88{
89 pub(crate) fn new(shared_reference: TypedSharedReference) -> Self {
90 Self {
91 shared_reference,
92 _t: PhantomData,
93 }
94 }
95
96 pub fn ptr_eq(this: &Self, other: &Self) -> bool {
97 triomphe::Arc::ptr_eq(&this.shared_reference.1.0, &other.shared_reference.1.0)
98 }
99}
100
101impl<T> TraitRef<T>
102where
103 T: VcValueTrait + ?Sized,
104{
105 pub fn cell(trait_ref: TraitRef<T>) -> Vc<T> {
108 let TraitRef {
109 shared_reference, ..
110 } = trait_ref;
111 let value_type = get_value_type(shared_reference.0);
112 (value_type.raw_cell)(shared_reference).into()
113 }
114}
115
116pub trait IntoTraitRef {
123 type ValueTrait: VcValueTrait + ?Sized;
124 type Future: Future<Output = Result<<VcValueTraitCast<Self::ValueTrait> as VcCast>::Output>>;
125
126 fn into_trait_ref(self) -> Self::Future;
127}
128
129impl<T> IntoTraitRef for Vc<T>
130where
131 T: VcValueTrait + ?Sized,
132{
133 type ValueTrait = T;
134
135 type Future = ReadVcFuture<T, VcValueTraitCast<T>>;
136
137 fn into_trait_ref(self) -> Self::Future {
138 self.node.into_read().into()
139 }
140}