1use std::mem::take;
2
3use crate::{
4 declare_trait_object_with_archived, derive_comparison_traits, dynamic::erase::Erase,
5 utils::Tup2, DBData,
6};
7
8use super::{Data, DataTrait, DowncastTrait};
9use crate::utils::ArchivedTup2;
10
11use crate::dynamic::rkyv::{ArchivedDBData, DeserializeDyn, DeserializeImpl};
12
13pub trait Pair<T1: DataTrait + ?Sized, T2: DataTrait + ?Sized>: Data {
15 fn fst(&self) -> &T1;
17
18 fn snd(&self) -> &T2;
20
21 fn fst_mut(&mut self) -> &mut T1;
23
24 fn snd_mut(&mut self) -> &mut T2;
26
27 fn split(&self) -> (&T1, &T2);
29
30 fn split_mut(&mut self) -> (&mut T1, &mut T2);
32
33 #[allow(clippy::wrong_self_convention)]
35 fn from_refs(&mut self, fst: &T1, snd: &T2);
36
37 #[allow(clippy::wrong_self_convention)]
40 fn from_vals(&mut self, fst: &mut T1, snd: &mut T2);
41}
42
43impl<T1, T2, Trait1, Trait2> Pair<Trait1, Trait2> for Tup2<T1, T2>
44where
45 T1: DBData + Erase<Trait1>,
46 T2: DBData + Erase<Trait2>,
47 Trait1: DataTrait + ?Sized,
48 Trait2: DataTrait + ?Sized,
49{
50 fn fst(&self) -> &Trait1 {
51 self.0.erase()
52 }
53
54 fn fst_mut(&mut self) -> &mut Trait1 {
55 self.0.erase_mut()
56 }
57
58 fn snd(&self) -> &Trait2 {
59 self.1.erase()
60 }
61
62 fn snd_mut(&mut self) -> &mut Trait2 {
63 self.1.erase_mut()
64 }
65
66 fn split(&self) -> (&Trait1, &Trait2) {
67 (self.0.erase(), self.1.erase())
68 }
69
70 fn split_mut(&mut self) -> (&mut Trait1, &mut Trait2) {
71 (self.0.erase_mut(), self.1.erase_mut())
72 }
73
74 fn from_refs(&mut self, fst: &Trait1, snd: &Trait2) {
75 unsafe {
76 self.0 = fst.downcast::<T1>().clone();
77 self.1 = snd.downcast::<T2>().clone();
78 }
79 }
80
81 fn from_vals(&mut self, fst: &mut Trait1, snd: &mut Trait2) {
82 unsafe {
83 self.0 = take(fst.downcast_mut::<T1>());
84 self.1 = take(snd.downcast_mut::<T2>());
85 }
86 }
87}
88
89pub trait ArchivedPair<T1: DataTrait + ?Sized, T2: DataTrait + ?Sized> {
90 fn fst(&self) -> &T1::Archived;
91 fn snd(&self) -> &T2::Archived;
92 fn split(&self) -> (&T1::Archived, &T2::Archived);
93}
94
95impl<T1, T2, Trait1, Trait2> ArchivedPair<Trait1, Trait2> for ArchivedTup2<T1, T2>
96where
97 T1: DBData + Erase<Trait1>,
98 T2: DBData + Erase<Trait2>,
99 Trait1: DataTrait + ?Sized,
100 Trait2: DataTrait + ?Sized,
101{
102 fn fst(&self) -> &Trait1::Archived {
103 <T1 as Erase<Trait1>>::erase_archived(&self.0)
104 }
105
106 fn snd(&self) -> &Trait2::Archived {
107 <T2 as Erase<Trait2>>::erase_archived(&self.1)
108 }
109
110 fn split(&self) -> (&Trait1::Archived, &Trait2::Archived) {
111 (
112 <T1 as Erase<Trait1>>::erase_archived(&self.0),
113 <T2 as Erase<Trait2>>::erase_archived(&self.1),
114 )
115 }
116}
117
118impl<T, Trait, Trait1, Trait2> ArchivedPair<Trait1, Trait2> for DeserializeImpl<T, Trait>
119where
120 T: ArchivedDBData + 'static,
121 T::Archived: ArchivedPair<Trait1, Trait2> + Ord + Eq,
122 Trait: Pair<Trait1, Trait2> + DowncastTrait + ?Sized + 'static,
123 Trait1: DataTrait + ?Sized,
124 Trait2: DataTrait + ?Sized,
125{
126 fn fst(&self) -> &Trait1::Archived {
127 self.archived.fst()
128 }
129
130 fn snd(&self) -> &Trait2::Archived {
131 self.archived.snd()
132 }
133
134 fn split(&self) -> (&Trait1::Archived, &Trait2::Archived) {
135 (self.archived.fst(), self.archived.snd())
136 }
137}
138
139pub trait ArchivedPairTrait<T1: DataTrait + ?Sized, T2: DataTrait + ?Sized>:
140 ArchivedPair<T1, T2> + DeserializeDyn<DynPair<T1, T2>>
141{
142}
143
144impl<Trait, T1, T2> ArchivedPairTrait<T1, T2> for Trait
145where
146 Trait: ArchivedPair<T1, T2> + DeserializeDyn<DynPair<T1, T2>> + ?Sized,
147 T1: DataTrait + ?Sized,
148 T2: DataTrait + ?Sized,
149{
150}
151
152type DynArchivedPair<Trait1, Trait2> = dyn ArchivedPairTrait<Trait1, Trait2>;
153
154derive_comparison_traits!(DynArchivedPair<Trait1, Trait2> where Trait1: DataTrait + ?Sized + 'static, Trait2: DataTrait + ?Sized + 'static);
155impl<Trait1: ?Sized + 'static, Trait2: ?Sized + 'static> DowncastTrait
156 for DynArchivedPair<Trait1, Trait2>
157{
158}
159
160declare_trait_object_with_archived!(DynPair<T1, T2> = dyn Pair<T1, T2>
161 { type Archived = dyn ArchivedPairTrait<T1, T2>}
162 where
163 T1: DataTrait + ?Sized,
164 T2: DataTrait + ?Sized,
165);