1use std::{fmt::Debug, marker::PhantomData, ops::Deref};
2
3use anyhow::Result;
4
5use crate::{
6 SharedReference,
7 trace::{TraceRawVcs, TraceRawVcsContext},
8};
9
10#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
15pub struct TransientValue<T> {
16 inner: T,
17}
18
19impl<T> TransientValue<T> {
20 pub fn new(value: T) -> Self {
21 Self { inner: value }
22 }
23
24 pub fn into_value(self) -> T {
25 self.inner
26 }
27}
28
29impl<T> Deref for TransientValue<T> {
30 type Target = T;
31
32 fn deref(&self) -> &Self::Target {
33 &self.inner
34 }
35}
36
37impl<T: TraceRawVcs> TraceRawVcs for TransientValue<T> {
38 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
39 self.inner.trace_raw_vcs(trace_context)
40 }
41}
42
43pub struct TransientInstance<T> {
51 inner: SharedReference,
52 phantom: PhantomData<T>,
53}
54
55impl<T> Debug for TransientInstance<T> {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 f.debug_tuple("TransientInstance").finish()
58 }
59}
60
61impl<T> Clone for TransientInstance<T> {
62 fn clone(&self) -> Self {
63 Self {
64 inner: self.inner.clone(),
65 phantom: self.phantom,
66 }
67 }
68}
69
70impl<T> Eq for TransientInstance<T> {}
71
72impl<T> PartialEq for TransientInstance<T> {
73 fn eq(&self, other: &Self) -> bool {
74 self.inner == other.inner
75 }
76}
77
78impl<T> std::hash::Hash for TransientInstance<T> {
79 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
80 self.inner.hash(state);
81 }
82}
83
84impl<T: Send + Sync + 'static> From<TransientInstance<T>> for triomphe::Arc<T> {
85 fn from(instance: TransientInstance<T>) -> Self {
86 instance.inner.downcast().unwrap()
88 }
89}
90
91impl<T: Send + Sync + 'static> From<TransientInstance<T>> for SharedReference {
92 fn from(instance: TransientInstance<T>) -> Self {
93 instance.inner
94 }
95}
96
97impl<T: Send + Sync + 'static> From<triomphe::Arc<T>> for TransientInstance<T> {
98 fn from(arc: triomphe::Arc<T>) -> Self {
99 Self {
100 inner: SharedReference::new(arc),
101 phantom: PhantomData,
102 }
103 }
104}
105
106impl<T: Send + Sync + 'static> TryFrom<SharedReference> for TransientInstance<T> {
107 type Error = ();
108
109 fn try_from(inner: SharedReference) -> Result<Self, Self::Error> {
110 if inner.0.downcast_ref::<T>().is_some() {
111 Ok(Self {
112 inner,
113 phantom: PhantomData,
114 })
115 } else {
116 Err(())
117 }
118 }
119}
120
121impl<T: Send + Sync + 'static> TransientInstance<T> {
122 pub fn new(value: T) -> Self {
123 Self {
124 inner: SharedReference::new(triomphe::Arc::new(value)),
125 phantom: PhantomData,
126 }
127 }
128}
129
130impl<T: 'static> Deref for TransientInstance<T> {
131 type Target = T;
132
133 fn deref(&self) -> &Self::Target {
134 self.inner.0.downcast_ref().unwrap()
135 }
136}
137
138impl<T: TraceRawVcs + 'static> TraceRawVcs for TransientInstance<T> {
139 fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
140 self.inner.downcast_ref::<T>().trace_raw_vcs(trace_context)
141 }
142}