turbo_tasks/
magic_any.rs

1use core::fmt;
2use std::{
3    any::{Any, TypeId},
4    fmt::Debug,
5    hash::Hash,
6    sync::Arc,
7};
8
9use serde::{Deserialize, Serialize, de::DeserializeSeed};
10use turbo_dyn_eq_hash::{
11    DynEq, DynHash, DynPartialEq, impl_eq_for_dyn, impl_hash_for_dyn, impl_partial_eq_for_dyn,
12};
13
14use crate::trace::{TraceRawVcs, TraceRawVcsContext};
15
16pub trait MagicAny: mopa::Any + DynPartialEq + DynEq + DynHash + Send + Sync {
17    fn magic_any_arc(self: Arc<Self>) -> Arc<dyn Any + Sync + Send>;
18
19    fn magic_debug(&self, f: &mut fmt::Formatter) -> fmt::Result;
20
21    fn magic_trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext);
22
23    #[cfg(debug_assertions)]
24    fn magic_type_name(&self) -> &'static str;
25}
26
27#[allow(clippy::transmute_ptr_to_ref)] // can't fix as it's in the macro
28mod clippy {
29    use mopa::mopafy;
30
31    use super::MagicAny;
32
33    mopafy!(MagicAny);
34}
35
36impl<T: Debug + Eq + Hash + Send + Sync + TraceRawVcs + 'static> MagicAny for T {
37    fn magic_any_arc(self: Arc<Self>) -> Arc<dyn Any + Sync + Send> {
38        self
39    }
40
41    fn magic_debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
42        let mut d = f.debug_tuple("MagicAny");
43        d.field(&TypeId::of::<Self>());
44
45        #[cfg(debug_assertions)]
46        d.field(&std::any::type_name::<Self>());
47
48        d.field(&(self as &Self));
49        d.finish()
50    }
51
52    fn magic_trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
53        self.trace_raw_vcs(trace_context);
54    }
55
56    #[cfg(debug_assertions)]
57    fn magic_type_name(&self) -> &'static str {
58        std::any::type_name::<T>()
59    }
60}
61
62impl fmt::Debug for dyn MagicAny {
63    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64        self.magic_debug(f)
65    }
66}
67
68impl_partial_eq_for_dyn!(dyn MagicAny);
69impl_eq_for_dyn!(dyn MagicAny);
70impl_hash_for_dyn!(dyn MagicAny);
71
72impl TraceRawVcs for dyn MagicAny {
73    fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) {
74        self.magic_trace_raw_vcs(trace_context)
75    }
76}
77
78impl dyn MagicAny {
79    pub fn as_serialize<T: Debug + Eq + Hash + Serialize + Send + Sync + TraceRawVcs + 'static>(
80        &self,
81    ) -> &dyn erased_serde::Serialize {
82        if let Some(r) = self.downcast_ref::<T>() {
83            r
84        } else {
85            #[cfg(debug_assertions)]
86            panic!(
87                "MagicAny::as_serializable broken: got {} but expected {}",
88                self.magic_type_name(),
89                std::any::type_name::<T>()
90            );
91            #[cfg(not(debug_assertions))]
92            panic!("MagicAny::as_serializable bug");
93        }
94    }
95}
96
97type MagicAnySerializeFunctor = fn(&dyn MagicAny) -> &dyn erased_serde::Serialize;
98
99#[derive(Clone, Copy)]
100pub struct MagicAnySerializeSeed {
101    functor: MagicAnySerializeFunctor,
102}
103
104impl MagicAnySerializeSeed {
105    pub fn new<T: Debug + Eq + Hash + Serialize + Send + Sync + TraceRawVcs + 'static>() -> Self {
106        fn serialize<T: Debug + Eq + Hash + Serialize + Send + Sync + TraceRawVcs + 'static>(
107            value: &dyn MagicAny,
108        ) -> &dyn erased_serde::Serialize {
109            value.as_serialize::<T>()
110        }
111        Self {
112            functor: serialize::<T>,
113        }
114    }
115
116    pub fn as_serialize<'a>(&self, value: &'a dyn MagicAny) -> &'a dyn erased_serde::Serialize {
117        (self.functor)(value)
118    }
119}
120
121type MagicAnyDeserializeSeedFunctor =
122    fn(&mut dyn erased_serde::Deserializer<'_>) -> Result<Box<dyn MagicAny>, erased_serde::Error>;
123
124#[derive(Clone, Copy)]
125pub struct MagicAnyDeserializeSeed {
126    functor: MagicAnyDeserializeSeedFunctor,
127}
128
129impl MagicAnyDeserializeSeed {
130    pub fn new<T>() -> Self
131    where
132        T: for<'de> Deserialize<'de> + Debug + Eq + Hash + Send + Sync + TraceRawVcs + 'static,
133    {
134        fn deserialize<T>(
135            deserializer: &mut dyn erased_serde::Deserializer<'_>,
136        ) -> Result<Box<dyn MagicAny>, erased_serde::Error>
137        where
138            T: for<'de> Deserialize<'de> + Debug + Eq + Hash + Send + Sync + TraceRawVcs + 'static,
139        {
140            let value: T = erased_serde::deserialize(deserializer)?;
141            Ok(Box::new(value))
142        }
143        Self {
144            functor: deserialize::<T>,
145        }
146    }
147}
148
149impl<'de> DeserializeSeed<'de> for MagicAnyDeserializeSeed {
150    type Value = Box<dyn MagicAny>;
151
152    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
153    where
154        D: serde::Deserializer<'de>,
155    {
156        let mut deserializer = <dyn erased_serde::Deserializer>::erase(deserializer);
157        (self.functor)(&mut deserializer).map_err(serde::de::Error::custom)
158    }
159}
160
161type AnyDeserializeSeedFunctor = fn(
162    &mut dyn erased_serde::Deserializer<'_>,
163) -> Result<Box<dyn Any + Sync + Send>, erased_serde::Error>;
164
165#[derive(Clone, Copy)]
166pub struct AnyDeserializeSeed {
167    functor: AnyDeserializeSeedFunctor,
168}
169
170impl AnyDeserializeSeed {
171    pub fn new<T>() -> Self
172    where
173        T: for<'de> Deserialize<'de> + Any + Send + Sync + 'static,
174    {
175        fn deserialize<T: Any + for<'de> Deserialize<'de> + Send + Sync + 'static>(
176            deserializer: &mut dyn erased_serde::Deserializer<'_>,
177        ) -> Result<Box<dyn Any + Sync + Send>, erased_serde::Error> {
178            let value: T = erased_serde::deserialize(deserializer)?;
179            Ok(Box::new(value))
180        }
181        Self {
182            functor: deserialize::<T>,
183        }
184    }
185}
186
187impl<'de> DeserializeSeed<'de> for AnyDeserializeSeed {
188    type Value = Box<dyn Any + Sync + Send>;
189
190    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
191    where
192        D: serde::Deserializer<'de>,
193    {
194        let mut deserializer = <dyn erased_serde::Deserializer>::erase(deserializer);
195        (self.functor)(&mut deserializer).map_err(serde::de::Error::custom)
196    }
197}