1use std::{fmt::Debug, marker::PhantomData, ops::Deref};
2
3use anyhow::Result;
4use serde::{Deserialize, Serialize};
5
6use crate::{
7 ReadRef, SharedReference,
8 debug::{ValueDebugFormat, ValueDebugString},
9 trace::{TraceRawVcs, TraceRawVcsContext},
10};
11
12#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
16pub struct Value<T> {
17 inner: T,
18}
19
20impl<T> Value<T> {
21 pub fn new(value: T) -> Self {
22 Self { inner: value }
23 }
24
25 pub fn into_value(self) -> T {
26 self.inner
27 }
28}
29
30impl<T> Deref for Value<T> {
31 type Target = T;
32
33 fn deref(&self) -> &Self::Target {
34 &self.inner
35 }
36}
37
38impl<T: Copy> Copy for Value<T> {}
39
40impl<T: Default> Default for Value<T> {
41 fn default() -> Self {
42 Value::new(Default::default())
43 }
44}
45
46impl<T: ValueDebugFormat> Value<T> {
47 pub async fn dbg(&self) -> Result<ReadRef<ValueDebugString>> {
48 self.dbg_depth(usize::MAX).await
49 }
50
51 pub async fn dbg_depth(&self, depth: usize) -> Result<ReadRef<ValueDebugString>> {
52 self.inner
53 .value_debug_format(depth)
54 .try_to_value_debug_string()
55 .await?
56 .await
57 }
58}
59
60impl<T: TraceRawVcs> TraceRawVcs for Value<T> {
61 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
62 self.inner.trace_raw_vcs(trace_context)
63 }
64}
65
66#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
71pub struct TransientValue<T> {
72 inner: T,
73}
74
75impl<T> TransientValue<T> {
76 pub fn new(value: T) -> Self {
77 Self { inner: value }
78 }
79
80 pub fn into_value(self) -> T {
81 self.inner
82 }
83}
84
85impl<T> Deref for TransientValue<T> {
86 type Target = T;
87
88 fn deref(&self) -> &Self::Target {
89 &self.inner
90 }
91}
92
93impl<T: TraceRawVcs> TraceRawVcs for TransientValue<T> {
94 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
95 self.inner.trace_raw_vcs(trace_context)
96 }
97}
98
99pub struct TransientInstance<T> {
107 inner: SharedReference,
108 phantom: PhantomData<T>,
109}
110
111impl<T> Debug for TransientInstance<T> {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 f.debug_tuple("TransientInstance").finish()
114 }
115}
116
117impl<T> Clone for TransientInstance<T> {
118 fn clone(&self) -> Self {
119 Self {
120 inner: self.inner.clone(),
121 phantom: self.phantom,
122 }
123 }
124}
125
126impl<T> Eq for TransientInstance<T> {}
127
128impl<T> PartialEq for TransientInstance<T> {
129 fn eq(&self, other: &Self) -> bool {
130 self.inner == other.inner
131 }
132}
133
134impl<T> std::hash::Hash for TransientInstance<T> {
135 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
136 self.inner.hash(state);
137 }
138}
139
140impl<T: Send + Sync + 'static> From<TransientInstance<T>> for triomphe::Arc<T> {
141 fn from(instance: TransientInstance<T>) -> Self {
142 instance.inner.downcast().unwrap()
144 }
145}
146
147impl<T: Send + Sync + 'static> From<TransientInstance<T>> for SharedReference {
148 fn from(instance: TransientInstance<T>) -> Self {
149 instance.inner
150 }
151}
152
153impl<T: Send + Sync + 'static> From<triomphe::Arc<T>> for TransientInstance<T> {
154 fn from(arc: triomphe::Arc<T>) -> Self {
155 Self {
156 inner: SharedReference::new(arc),
157 phantom: PhantomData,
158 }
159 }
160}
161
162impl<T: Send + Sync + 'static> TryFrom<SharedReference> for TransientInstance<T> {
163 type Error = ();
164
165 fn try_from(inner: SharedReference) -> Result<Self, Self::Error> {
166 if inner.0.downcast_ref::<T>().is_some() {
167 Ok(Self {
168 inner,
169 phantom: PhantomData,
170 })
171 } else {
172 Err(())
173 }
174 }
175}
176
177impl<T: Send + Sync + 'static> TransientInstance<T> {
178 pub fn new(value: T) -> Self {
179 Self {
180 inner: SharedReference::new(triomphe::Arc::new(value)),
181 phantom: PhantomData,
182 }
183 }
184}
185
186impl<T: 'static> Deref for TransientInstance<T> {
187 type Target = T;
188
189 fn deref(&self) -> &Self::Target {
190 self.inner.0.downcast_ref().unwrap()
191 }
192}
193
194impl<T: TraceRawVcs + 'static> TraceRawVcs for TransientInstance<T> {
195 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
196 self.inner.downcast_ref::<T>().trace_raw_vcs(trace_context)
197 }
198}