topcoat_runtime/surrogate/
tuple.rs1use std::ops::Deref;
2
3use crate::{Surrogate, Surrogated};
4
5impl Surrogated for () {
6 type Surrogate = ();
7 fn into_surrogate(self) -> Self::Surrogate {}
8}
9
10impl Surrogate for () {
11 type Real = ();
12 fn into_real(self) -> Self::Real {}
13}
14
15pub trait TupleProject<'a> {
17 type Projected;
19
20 fn project(&'a self) -> Self::Projected;
21}
22
23pub struct TupleRefSurrogate<'a, T>
28where
29 T: TupleProject<'a>,
30{
31 real: &'a T,
32 projected: T::Projected,
33}
34
35impl<'a, T> TupleRefSurrogate<'a, T>
36where
37 T: TupleProject<'a>,
38{
39 fn new(real: &'a T) -> Self {
40 Self {
41 real,
42 projected: real.project(),
43 }
44 }
45}
46
47impl<'a, T> TupleRefSurrogate<'a, T>
48where
49 T: TupleProject<'a> + Surrogated + Clone,
50{
51 #[must_use]
54 #[allow(clippy::should_implement_trait)]
55 pub fn clone(&self) -> T::Surrogate {
56 self.real.clone().into_surrogate()
57 }
58}
59
60impl<'a, T> Deref for TupleRefSurrogate<'a, T>
61where
62 T: TupleProject<'a>,
63{
64 type Target = T::Projected;
65
66 fn deref(&self) -> &Self::Target {
67 &self.projected
68 }
69}
70
71impl<'a, T> serde::Serialize for TupleRefSurrogate<'a, T>
72where
73 T: TupleProject<'a>,
74 T::Projected: serde::Serialize,
75{
76 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
77 where
78 S: serde::Serializer,
79 {
80 self.projected.serialize(serializer)
81 }
82}
83
84macro_rules! impl_tuple_surrogate {
85 ($($t:ident $idx:tt),+ $(,)?) => {
86 impl<$($t),+> Surrogated for ($($t,)+)
87 where
88 $($t: Surrogated,)+
89 {
90 type Surrogate = ($(<$t as Surrogated>::Surrogate,)+);
91
92 fn into_surrogate(self) -> Self::Surrogate {
93 ($(self.$idx.into_surrogate(),)+)
94 }
95 }
96
97 impl<$($t),+> Surrogate for ($($t,)+)
98 where
99 $($t: Surrogate,)+
100 {
101 type Real = ($(<$t as Surrogate>::Real,)+);
102
103 fn into_real(self) -> Self::Real {
104 ($(self.$idx.into_real(),)+)
105 }
106 }
107
108 impl<'a, $($t: 'a),+> TupleProject<'a> for ($($t,)+)
109 where
110 $(&'a $t: Surrogated,)+
111 {
112 type Projected = ($(<&'a $t as Surrogated>::Surrogate,)+);
113
114 fn project(&'a self) -> Self::Projected {
115 ($((&self.$idx).into_surrogate(),)+)
116 }
117 }
118
119 impl<'a, $($t: 'a),+> Surrogated for &'a ($($t,)+)
120 where
121 $(&'a $t: Surrogated,)+
122 {
123 type Surrogate = TupleRefSurrogate<'a, ($($t,)+)>;
124
125 fn into_surrogate(self) -> Self::Surrogate {
126 TupleRefSurrogate::new(self)
127 }
128 }
129
130 impl<'a, $($t: 'a),+> Surrogate for TupleRefSurrogate<'a, ($($t,)+)>
131 where
132 $(&'a $t: Surrogated,)+
133 {
134 type Real = &'a ($($t,)+);
135
136 fn into_real(self) -> Self::Real {
137 self.real
138 }
139 }
140 };
141}
142
143impl_tuple_surrogate!(T1 0);
144impl_tuple_surrogate!(T1 0, T2 1);
145impl_tuple_surrogate!(T1 0, T2 1, T3 2);
146impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3);
147impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4);
148impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4, T6 5);
149impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4, T6 5, T7 6);
150impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4, T6 5, T7 6, T8 7);
151impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4, T6 5, T7 6, T8 7, T9 8);
152impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4, T6 5, T7 6, T8 7, T9 8, T10 9);
153impl_tuple_surrogate!(T1 0, T2 1, T3 2, T4 3, T5 4, T6 5, T7 6, T8 7, T9 8, T10 9, T11 10);
154impl_tuple_surrogate!(
155 T1 0, T2 1, T3 2, T4 3, T5 4, T6 5, T7 6, T8 7, T9 8, T10 9, T11 10, T12 11,
156);