1use std::{borrow::Cow, rc::Rc, sync::Arc};
2
3use crate::{AsWrap, either::Either};
4
5use super::{CellBuilder, CellBuilderError, CellSerialize};
6
7pub trait CellSerializeAs<T: ?Sized> {
13 type Args;
14
15 fn store_as(
17 source: &T,
18 builder: &mut CellBuilder,
19 args: Self::Args,
20 ) -> Result<(), CellBuilderError>;
21}
22
23impl<'a, T, As> CellSerializeAs<&'a T> for &'a As
24where
25 T: ?Sized,
26 As: CellSerializeAs<T> + ?Sized,
27{
28 type Args = As::Args;
29
30 #[inline]
31 fn store_as(
32 source: &&'a T,
33 builder: &mut CellBuilder,
34 args: Self::Args,
35 ) -> Result<(), CellBuilderError> {
36 AsWrap::<&T, As>::new(source).store(builder, args)
37 }
38}
39
40impl<'a, T, As> CellSerializeAs<&'a mut T> for &'a mut As
41where
42 T: ?Sized,
43 As: CellSerializeAs<T> + ?Sized,
44{
45 type Args = As::Args;
46
47 #[inline]
48 fn store_as(
49 source: &&'a mut T,
50 builder: &mut CellBuilder,
51 args: Self::Args,
52 ) -> Result<(), CellBuilderError> {
53 AsWrap::<&T, As>::new(source).store(builder, args)
54 }
55}
56
57impl<T, As> CellSerializeAs<[T]> for [As]
58where
59 As: CellSerializeAs<T>,
60 As::Args: Clone,
61{
62 type Args = As::Args;
63
64 #[inline]
65 fn store_as(
66 source: &[T],
67 builder: &mut CellBuilder,
68 args: Self::Args,
69 ) -> Result<(), CellBuilderError> {
70 builder.store_many_as::<_, &As>(source, args)?;
71 Ok(())
72 }
73}
74
75impl<T, As, const N: usize> CellSerializeAs<[T; N]> for [As; N]
76where
77 As: CellSerializeAs<T>,
78 As::Args: Clone,
79{
80 type Args = As::Args;
81
82 #[inline]
83 fn store_as(
84 source: &[T; N],
85 builder: &mut CellBuilder,
86 args: Self::Args,
87 ) -> Result<(), CellBuilderError> {
88 <[As]>::store_as(source, builder, args)
89 }
90}
91
92macro_rules! impl_cell_serialize_as_for_tuple {
93 ($($n:tt:$t:ident as $a:ident),+) => {
94 impl<$($t, $a),+> CellSerializeAs<($($t,)+)> for ($($a,)+)
95 where $(
96 $a: CellSerializeAs<$t>,
97 )+
98 {
99 type Args = ($($a::Args,)+);
100
101 #[inline]
102 fn store_as(source: &($($t,)+), builder: &mut CellBuilder, args: Self::Args) -> Result<(), CellBuilderError> {
103 builder$(
104 .store_as::<&$t, &$a>(&source.$n, args.$n)?)+;
105 Ok(())
106 }
107 }
108 };
109}
110impl_cell_serialize_as_for_tuple!(0:T0 as As0);
111impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1);
112impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2);
113impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3);
114impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3,4:T4 as As4);
115impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3,4:T4 as As4,5:T5 as As5);
116impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3,4:T4 as As4,5:T5 as As5,6:T6 as As6);
117impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3,4:T4 as As4,5:T5 as As5,6:T6 as As6,7:T7 as As7);
118impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3,4:T4 as As4,5:T5 as As5,6:T6 as As6,7:T7 as As7,8:T8 as As8);
119impl_cell_serialize_as_for_tuple!(0:T0 as As0,1:T1 as As1,2:T2 as As2,3:T3 as As3,4:T4 as As4,5:T5 as As5,6:T6 as As6,7:T7 as As7,8:T8 as As8,9:T9 as As9);
120
121impl<T, As> CellSerializeAs<Box<T>> for Box<As>
122where
123 As: CellSerializeAs<T> + ?Sized,
124{
125 type Args = As::Args;
126
127 #[inline]
128 fn store_as(
129 source: &Box<T>,
130 builder: &mut CellBuilder,
131 args: Self::Args,
132 ) -> Result<(), CellBuilderError> {
133 AsWrap::<&T, As>::new(source).store(builder, args)
134 }
135}
136
137impl<T, As> CellSerializeAs<Rc<T>> for Rc<As>
138where
139 As: CellSerializeAs<T> + ?Sized,
140{
141 type Args = As::Args;
142
143 #[inline]
144 fn store_as(
145 source: &Rc<T>,
146 builder: &mut CellBuilder,
147 args: Self::Args,
148 ) -> Result<(), CellBuilderError> {
149 AsWrap::<&T, As>::new(source).store(builder, args)
150 }
151}
152
153impl<T, As> CellSerializeAs<Arc<T>> for Arc<As>
154where
155 As: CellSerializeAs<T> + ?Sized,
156{
157 type Args = As::Args;
158
159 #[inline]
160 fn store_as(
161 source: &Arc<T>,
162 builder: &mut CellBuilder,
163 args: Self::Args,
164 ) -> Result<(), CellBuilderError> {
165 AsWrap::<&T, As>::new(source).store(builder, args)
166 }
167}
168
169impl<'a, T, As> CellSerializeAs<Cow<'a, T>> for Cow<'a, As>
170where
171 T: ToOwned + ?Sized,
172 As: ToOwned + CellSerializeAs<T> + ?Sized,
173{
174 type Args = As::Args;
175
176 #[inline]
177 fn store_as(
178 source: &Cow<'a, T>,
179 builder: &mut CellBuilder,
180 args: Self::Args,
181 ) -> Result<(), CellBuilderError> {
182 AsWrap::<&T, As>::new(source).store(builder, args)
183 }
184}
185
186impl<Left, Right, AsLeft, AsRight> CellSerializeAs<Either<Left, Right>> for Either<AsLeft, AsRight>
192where
193 AsLeft: CellSerializeAs<Left>,
194 AsRight: CellSerializeAs<Right>,
195{
196 type Args = (AsLeft::Args, AsRight::Args);
198
199 #[inline]
200 fn store_as(
201 source: &Either<Left, Right>,
202 builder: &mut CellBuilder,
203 args: Self::Args,
204 ) -> Result<(), CellBuilderError> {
205 source
206 .as_ref()
207 .map_either(AsWrap::<&Left, AsLeft>::new, AsWrap::<&Right, AsRight>::new)
208 .store(builder, args)
209 }
210}
211
212impl<T, As> CellSerializeAs<Option<T>> for Either<(), As>
213where
214 As: CellSerializeAs<T>,
215{
216 type Args = As::Args;
217
218 #[inline]
219 fn store_as(
220 source: &Option<T>,
221 builder: &mut CellBuilder,
222 args: Self::Args,
223 ) -> Result<(), CellBuilderError> {
224 source
225 .as_ref()
226 .map(AsWrap::<&T, As>::new)
227 .map_or(Either::Left(()), Either::Right)
228 .store(builder, ((), args))
229 }
230}
231
232impl<T, As> CellSerializeAs<Option<T>> for Option<As>
238where
239 As: CellSerializeAs<T>,
240{
241 type Args = As::Args;
242
243 #[inline]
244 fn store_as(
245 source: &Option<T>,
246 builder: &mut CellBuilder,
247 args: Self::Args,
248 ) -> Result<(), CellBuilderError> {
249 source
250 .as_ref()
251 .map(AsWrap::<_, As>::new)
252 .store(builder, args)
253 }
254}
255
256pub trait CellSerializeWrapAsExt {
257 #[inline]
258 fn wrap_as<As>(&self) -> AsWrap<&'_ Self, As>
259 where
260 As: CellSerializeAs<Self> + ?Sized,
261 {
262 AsWrap::new(self)
263 }
264}
265impl<T> CellSerializeWrapAsExt for T {}