1use std::mem::take;
2
3use crate::{DBData, declare_trait_object, dynamic::erase::Erase, utils::Tup2};
4
5use super::{Data, DataTrait};
6
7pub trait Pair<T1: DataTrait + ?Sized, T2: DataTrait + ?Sized>: Data {
9 fn fst(&self) -> &T1;
11
12 fn snd(&self) -> &T2;
14
15 fn fst_mut(&mut self) -> &mut T1;
17
18 fn snd_mut(&mut self) -> &mut T2;
20
21 fn split(&self) -> (&T1, &T2);
23
24 fn split_mut(&mut self) -> (&mut T1, &mut T2);
26
27 #[allow(clippy::wrong_self_convention)]
29 fn from_refs(&mut self, fst: &T1, snd: &T2);
30
31 #[allow(clippy::wrong_self_convention)]
34 fn from_vals(&mut self, fst: &mut T1, snd: &mut T2);
35}
36
37impl<T1, T2, Trait1, Trait2> Pair<Trait1, Trait2> for Tup2<T1, T2>
38where
39 T1: DBData + Erase<Trait1>,
40 T2: DBData + Erase<Trait2>,
41 Trait1: DataTrait + ?Sized,
42 Trait2: DataTrait + ?Sized,
43{
44 fn fst(&self) -> &Trait1 {
45 self.0.erase()
46 }
47
48 fn fst_mut(&mut self) -> &mut Trait1 {
49 self.0.erase_mut()
50 }
51
52 fn snd(&self) -> &Trait2 {
53 self.1.erase()
54 }
55
56 fn snd_mut(&mut self) -> &mut Trait2 {
57 self.1.erase_mut()
58 }
59
60 fn split(&self) -> (&Trait1, &Trait2) {
61 (self.0.erase(), self.1.erase())
62 }
63
64 fn split_mut(&mut self) -> (&mut Trait1, &mut Trait2) {
65 (self.0.erase_mut(), self.1.erase_mut())
66 }
67
68 fn from_refs(&mut self, fst: &Trait1, snd: &Trait2) {
69 unsafe {
70 self.0 = fst.downcast::<T1>().clone();
71 self.1 = snd.downcast::<T2>().clone();
72 }
73 }
74
75 fn from_vals(&mut self, fst: &mut Trait1, snd: &mut Trait2) {
76 unsafe {
77 self.0 = take(fst.downcast_mut::<T1>());
78 self.1 = take(snd.downcast_mut::<T2>());
79 }
80 }
81}
82
83declare_trait_object!(DynPair<T1, T2> = dyn Pair<T1, T2>
84where
85 T1: DataTrait + ?Sized,
86 T2: DataTrait + ?Sized,
87);