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