1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use crate::{DBData, dynamic::rkyv::ArchiveTrait};
/// Type erasure operations.
///
/// Given a trait object type `Trait` such that `Self: Trait`, converts
/// references to self into references to `Trait`. The `Self: Trait` constraint
/// cannot be captured explicitly in the Rust type system, hence the need for this
/// trait.
pub trait Erase<Trait: ArchiveTrait + ?Sized> {
/// Convert a reference to `self` into a reference to `Trait`.
fn erase(&self) -> &Trait;
/// Convert a mutable reference to `self` into a mutable reference to `Trait`.
fn erase_mut(&mut self) -> &mut Trait;
/// Convert `Box<Self>` into `Box<Trait>`.
fn erase_box(self: Box<Self>) -> Box<Trait>;
/// Convert a reference to an archived representation of `Self` into a reference
/// to a trait object of type `Trait::Archived`.
fn erase_archived(archived: &Self::Archived) -> &<Trait as ArchiveTrait>::Archived
where
Self: DBData;
}
#[macro_export]
macro_rules! derive_erase {
(<$($generic:ident),*> $trait_bound:path
{ type Archived = dyn $archived_type:path }
where
$($bound:tt)*
) =>
{
impl<V, $($generic),*> $crate::dynamic::Erase<dyn $trait_bound> for V
where
V: $trait_bound + $crate::dynamic::ArchivedDBData,
$crate::dynamic::DeserializeImpl::<V, dyn $trait_bound>: $archived_type,
$($bound)*
{
fn erase(&self) -> &dyn $trait_bound {
self
}
fn erase_mut(&mut self) -> &mut dyn $trait_bound {
self
}
fn erase_box(self: Box<Self>) -> Box<dyn $trait_bound> {
self
}
fn erase_archived(
archived: &<Self as rkyv::Archive>::Archived,
) -> &<dyn $trait_bound as $crate::dynamic::ArchiveTrait>::Archived {
$crate::dynamic::DeserializeImpl::<V, dyn $trait_bound>::new(archived)
}
}
};
}