dbsp/dynamic/
declare_trait_object.rs1#[macro_export]
2macro_rules! declare_trait_object {
3 ($type_alias:ident <$($generic:ident),* > = dyn $typedef:path
4 where
5 $($bound:tt)*
6 ) =>
7 {
8 $crate::declare_trait_object_with_archived!($type_alias <$($generic),*> = dyn $typedef
9 { type Archived = dyn $crate::dynamic::DeserializeDyn<$type_alias<$($generic),*>> }
10 where
11 $($bound)*
12 );
13 }
14}
15
16#[macro_export]
17macro_rules! declare_trait_object_with_archived {
18 ($type_alias:ident <$($generic:ident),* > = dyn $typedef:path
19 { type Archived = dyn $archived_type:path }
20 where
21 $($bound:tt)*
22 ) =>
23 {
24 pub type $type_alias<$($generic),*> = dyn $typedef;
25
26 $crate::derive_comparison_traits!($type_alias<$($generic),*> where $($bound)*);
27 $crate::derive_erase!(<$($generic),*> $typedef
28 { type Archived = dyn $archived_type }
29 where $($bound)*);
30
31 impl<$($generic),*> $crate::dynamic::DowncastTrait for $type_alias<$($generic),*>
32 where
33 $($bound)*
34 {
35 }
36
37 impl<$($generic),*> std::hash::Hash for $type_alias<$($generic),*>
38 where
39 $($bound)*
40 {
41 fn hash<H>(&self, state: &mut H)
42 where H: std::hash::Hasher {
43 self.dyn_hash(state)
44 }
45 }
46
47 impl<$($generic),*> Clone for Box<$type_alias<$($generic),*>>
48 where
49 $($bound)*
50 {
51 fn clone(&self) -> Self {
52 dyn_clone::clone_box(self.as_ref())
53 }
54 }
55
56 impl<$($generic),*> rkyv::Deserialize<Box<$type_alias<$($generic),*>>, $crate::trace::Deserializer> for () {
57 fn deserialize(
58 &self,
59 _deserializer: &mut $crate::trace::Deserializer,
60 ) -> Result<Box<$type_alias<$($generic),*>>, <$crate::trace::Deserializer as rkyv::Fallible>::Error> {
61 todo!("deserialize {}", std::any::type_name::<Self>())
62 }
63 }
64
65 impl<$($generic),*> rkyv::Archive for Box<$type_alias<$($generic),*>> {
66 type Archived = ();
67 type Resolver = ();
68
69 unsafe fn resolve(&self, _pos: usize, _resolver: Self::Resolver, _out: *mut Self::Archived) {
70 todo!()
71 }
72 }
73
74 impl<$($generic),*> rkyv::Serialize<$crate::trace::DbspSerializer<'_>> for Box<$type_alias<$($generic),*>> {
75 fn serialize(
76 &self,
77 _serializer: &mut $crate::trace::DbspSerializer,
78 ) -> Result<Self::Resolver, <$crate::trace::DbspSerializer<'_> as rkyv::Fallible>::Error> {
79 todo!()
80 }
81 }
82
83 impl<$($generic),*> $crate::dynamic::ArchiveTrait for $type_alias<$($generic),*>
84 where
85 $($bound)*
86 {
87 type Archived = dyn $archived_type;
88 }
89 };
90}
91
92#[macro_export]
93macro_rules! declare_typed_trait_object {
94 ($type_alias:ident <$($generic:ident),* > = dyn $typedef:ty
95 [$inner_type:ty]
96 where
97 $($bound:tt)*
98 ) =>
99 {
100 $crate::declare_trait_object!($type_alias<$($generic),*> = dyn $typedef where $($bound)*);
101
102 impl<$($generic),*> std::ops::Deref for $type_alias<$($generic),*>
103 where
104 $($bound)*
105 {
106 type Target = $inner_type;
107
108 fn deref(&self) -> &Self::Target {
109 unsafe { &*(self as *const _ as *const Self::Target) }
110 }
111 }
112
113 impl<$($generic),*> std::ops::DerefMut for $type_alias<$($generic),*>
114 where
115 $($bound)*
116 {
117 fn deref_mut(&mut self) -> &mut Self::Target {
118 unsafe { &mut *(self as *mut _ as *mut $inner_type) }
119 }
120 }
121 };
122}
123
124#[cfg(test)]
125mod test {
126 use feldera_macros::IsNone;
127 use rkyv::{Archive, Deserialize, Serialize};
128 use size_of::SizeOf;
129
130 use crate::{
131 DBData, DBWeight,
132 dynamic::{Data, DataTrait, DataTraitTyped, Erase, WeightTrait, WeightTraitTyped},
133 };
134
135 #[derive(
136 Clone,
137 Default,
138 Debug,
139 PartialOrd,
140 Ord,
141 PartialEq,
142 Eq,
143 Hash,
144 SizeOf,
145 Archive,
146 Serialize,
147 Deserialize,
148 IsNone,
149 )]
150 #[archive_attr(derive(Ord, Eq, PartialEq, PartialOrd))]
151 #[archive(compare(PartialEq, PartialOrd))]
152 struct Foo<T1: DBData, T2: DBData> {
153 x: T1,
154 y: T2,
155 }
156
157 pub trait Bar<T1: DataTrait + ?Sized, T2: WeightTrait + ?Sized>: Data {
158 fn f1(&self) -> &T1;
159 fn f2(&self) -> &T2;
160 }
161
162 impl<T1: DataTraitTyped + ?Sized, T2: WeightTraitTyped + ?Sized> Bar<T1, T2>
163 for Foo<T1::Type, T2::Type>
164 where
165 T1::Type: DBData + Erase<T1>,
166 T2::Type: DBWeight + Erase<T2>,
167 {
168 fn f1(&self) -> &T1 {
169 self.x.erase()
170 }
171
172 fn f2(&self) -> &T2 {
173 self.y.erase()
174 }
175 }
176
177 declare_trait_object!(DynBar<T1, T2> = dyn Bar<T1, T2>
178 where
179 T1: DataTrait + ?Sized,
180 T2: WeightTrait + ?Sized
181 );
182
183 #[test]
184 fn declare_trait_object_test() {}
185}