1use std::{
2 fmt::{Debug, Display},
3 hash::Hash,
4 marker::PhantomData,
5 mem::transmute_copy,
6};
7
8use serde::{Deserialize, Serialize};
9use turbo_tasks_hash::DeterministicHash;
10
11use crate::{
12 SharedReference, Vc, VcRead, VcValueType,
13 debug::{ValueDebugFormat, ValueDebugFormatString},
14 trace::{TraceRawVcs, TraceRawVcsContext},
15 triomphe_utils::unchecked_sidecast_triomphe_arc,
16 vc::VcCellMode,
17};
18
19type VcReadTarget<T> = <<T as VcValueType>::Read as VcRead<T>>::Target;
20
21pub struct ReadRef<T>(triomphe::Arc<T>);
27
28impl<T> Clone for ReadRef<T> {
29 fn clone(&self) -> Self {
30 Self(self.0.clone())
31 }
32}
33
34impl<T> std::ops::Deref for ReadRef<T>
35where
36 T: VcValueType,
37{
38 type Target = VcReadTarget<T>;
39
40 fn deref(&self) -> &Self::Target {
41 T::Read::value_to_target_ref(&self.0)
42 }
43}
44
45impl<T> Display for ReadRef<T>
46where
47 T: VcValueType,
48 VcReadTarget<T>: Display,
49{
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 Display::fmt(&**self, f)
52 }
53}
54
55impl<T> Debug for ReadRef<T>
56where
57 T: VcValueType,
58 VcReadTarget<T>: Debug,
59{
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 Debug::fmt(&**self, f)
62 }
63}
64
65impl<T> TraceRawVcs for ReadRef<T>
66where
67 T: VcValueType,
68 VcReadTarget<T>: TraceRawVcs,
69{
70 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
71 (**self).trace_raw_vcs(trace_context);
72 }
73}
74
75impl<T> ValueDebugFormat for ReadRef<T>
76where
77 T: VcValueType,
78 VcReadTarget<T>: ValueDebugFormat + 'static,
79{
80 fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString {
81 let value = &**self;
82 value.value_debug_format(depth)
83 }
84}
85
86impl<T> PartialEq for ReadRef<T>
87where
88 T: VcValueType,
89 VcReadTarget<T>: PartialEq,
90{
91 fn eq(&self, other: &Self) -> bool {
92 PartialEq::eq(&**self, &**other)
93 }
94}
95
96impl<T> Eq for ReadRef<T>
97where
98 T: VcValueType,
99 VcReadTarget<T>: Eq,
100{
101}
102
103impl<T> PartialOrd for ReadRef<T>
104where
105 T: VcValueType,
106 VcReadTarget<T>: PartialOrd,
107{
108 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
109 PartialOrd::partial_cmp(&**self, &**other)
110 }
111}
112
113impl<T> Ord for ReadRef<T>
114where
115 T: VcValueType,
116 VcReadTarget<T>: Ord,
117{
118 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
119 Ord::cmp(&**self, &**other)
120 }
121}
122
123impl<T> Hash for ReadRef<T>
124where
125 T: VcValueType,
126 VcReadTarget<T>: Hash,
127{
128 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
129 Hash::hash(&**self, state)
130 }
131}
132
133impl<T> DeterministicHash for ReadRef<T>
134where
135 T: VcValueType,
136 VcReadTarget<T>: DeterministicHash,
137{
138 fn deterministic_hash<H: turbo_tasks_hash::DeterministicHasher>(&self, state: &mut H) {
139 let p = &**self;
140 p.deterministic_hash(state);
141 }
142}
143
144impl<'a, T, I, J: Iterator<Item = I>> IntoIterator for &'a ReadRef<T>
145where
146 T: VcValueType,
147 &'a VcReadTarget<T>: IntoIterator<Item = I, IntoIter = J>,
148{
149 type Item = I;
150
151 type IntoIter = J;
152
153 fn into_iter(self) -> Self::IntoIter {
154 (&**self).into_iter()
155 }
156}
157
158impl<T, I: 'static, J: Iterator<Item = I>> IntoIterator for ReadRef<T>
159where
160 T: VcValueType,
161 &'static VcReadTarget<T>: IntoIterator<Item = I, IntoIter = J>,
162{
163 type Item = I;
164
165 type IntoIter = ReadRefIter<T, I, J>;
166
167 fn into_iter(self) -> Self::IntoIter {
168 let r = &*self;
169 let r = unsafe { transmute_copy::<&'_ VcReadTarget<T>, &'static VcReadTarget<T>>(&r) };
172 ReadRefIter {
173 read_ref: self,
174 iter: r.into_iter(),
175 }
176 }
177}
178
179pub struct ReadRefIter<T, I: 'static, J: Iterator<Item = I>>
180where
181 T: VcValueType,
182{
183 iter: J,
184 #[allow(dead_code)]
185 read_ref: ReadRef<T>,
186}
187
188impl<T, I: 'static, J: Iterator<Item = I>> Iterator for ReadRefIter<T, I, J>
189where
190 T: VcValueType,
191{
192 type Item = I;
193
194 fn next(&mut self) -> Option<Self::Item> {
195 self.iter.next()
196 }
197}
198
199impl<T> Serialize for ReadRef<T>
200where
201 T: VcValueType,
202 VcReadTarget<T>: Serialize,
203{
204 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
205 where
206 S: serde::Serializer,
207 {
208 (**self).serialize(serializer)
209 }
210}
211
212impl<'de, T> Deserialize<'de> for ReadRef<T>
213where
214 T: Deserialize<'de>,
215{
216 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
217 where
218 D: serde::Deserializer<'de>,
219 {
220 let value = T::deserialize(deserializer)?;
221 Ok(Self(triomphe::Arc::new(value)))
222 }
223}
224
225impl<T> ReadRef<T> {
226 pub fn new_owned(value: T) -> Self {
227 Self(triomphe::Arc::new(value))
228 }
229
230 pub fn new_arc(arc: triomphe::Arc<T>) -> Self {
231 Self(arc)
232 }
233
234 pub fn ptr_eq(&self, other: &ReadRef<T>) -> bool {
235 triomphe::Arc::ptr_eq(&self.0, &other.0)
236 }
237
238 pub fn ptr(&self) -> *const T {
239 &*self.0 as *const T
240 }
241}
242
243impl<T> ReadRef<T>
244where
245 T: VcValueType,
246{
247 pub fn cell(read_ref: ReadRef<T>) -> Vc<T> {
250 let type_id = T::get_value_type_id();
251 let value = unsafe {
254 unchecked_sidecast_triomphe_arc::<T, <T::Read as VcRead<T>>::Repr>(read_ref.0)
255 };
256 Vc {
257 node: <T::CellMode as VcCellMode<T>>::raw_cell(
258 SharedReference::new(value).into_typed(type_id),
259 ),
260 _t: PhantomData,
261 }
262 }
263}
264
265impl<T> ReadRef<T>
266where
267 T: VcValueType,
268{
269 pub fn try_unwrap(this: Self) -> Result<VcReadTarget<T>, Self> {
273 match triomphe::Arc::try_unwrap(this.0) {
274 Ok(value) => Ok(T::Read::value_to_target(value)),
275 Err(arc) => Err(Self(arc)),
276 }
277 }
278}
279
280impl<T> ReadRef<T>
281where
282 T: VcValueType,
283 VcReadTarget<T>: Clone,
284{
285 pub fn into_owned(this: Self) -> VcReadTarget<T> {
288 Self::try_unwrap(this).unwrap_or_else(|this| (*this).clone())
289 }
290}