Skip to main content

dbsp/dynamic/
declare_trait_object.rs

1#[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}