1use crate::{
2 boxed::{ArchivedBox, BoxResolver},
3 niche::option_nonzero::{
4 ArchivedOptionNonZeroI128, ArchivedOptionNonZeroI16, ArchivedOptionNonZeroI32,
5 ArchivedOptionNonZeroI64, ArchivedOptionNonZeroI8, ArchivedOptionNonZeroU128,
6 ArchivedOptionNonZeroU16, ArchivedOptionNonZeroU32, ArchivedOptionNonZeroU64,
7 ArchivedOptionNonZeroU8,
8 },
9 option::ArchivedOption,
10 with::{
11 ArchiveWith, AsBox, DeserializeWith, Inline, Map, Niche, RefAsBox, SerializeWith, Skip,
12 Unsafe,
13 },
14 Archive, ArchiveUnsized, Deserialize, Fallible, Serialize, SerializeUnsized,
15};
16use ::core::{
17 cell::{Cell, UnsafeCell},
18 convert::TryInto,
19 hint::unreachable_unchecked,
20 num::{
21 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
22 NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
23 },
24 ptr,
25};
26
27impl<A, O> ArchiveWith<Option<O>> for Map<A>
31where
32 A: ArchiveWith<O>,
33{
34 type Archived = ArchivedOption<<A as ArchiveWith<O>>::Archived>;
35 type Resolver = Option<<A as ArchiveWith<O>>::Resolver>;
36
37 unsafe fn resolve_with(
38 field: &Option<O>,
39 pos: usize,
40 resolver: Self::Resolver,
41 out: *mut Self::Archived,
42 ) {
43 match resolver {
44 None => {
45 let out = out.cast::<ArchivedOptionVariantNone>();
46 ptr::addr_of_mut!((*out).0).write(ArchivedOptionTag::None);
47 }
48 Some(resolver) => {
49 let out = out.cast::<ArchivedOptionVariantSome<<A as ArchiveWith<O>>::Archived>>();
50 ptr::addr_of_mut!((*out).0).write(ArchivedOptionTag::Some);
51
52 let value = if let Some(value) = field.as_ref() {
53 value
54 } else {
55 unreachable_unchecked();
56 };
57
58 let (fp, fo) = out_field!(out.1);
59 A::resolve_with(value, pos + fp, resolver, fo);
60 }
61 }
62 }
63}
64
65impl<A, O, S> SerializeWith<Option<O>, S> for Map<A>
66where
67 S: Fallible + ?Sized,
68 A: ArchiveWith<O> + SerializeWith<O, S>,
69{
70 fn serialize_with(field: &Option<O>, s: &mut S) -> Result<Self::Resolver, S::Error> {
71 field
72 .as_ref()
73 .map(|value| A::serialize_with(value, s))
74 .transpose()
75 }
76}
77
78impl<A, O, D> DeserializeWith<ArchivedOption<<A as ArchiveWith<O>>::Archived>, Option<O>, D>
79 for Map<A>
80where
81 D: Fallible + ?Sized,
82 A: ArchiveWith<O> + DeserializeWith<<A as ArchiveWith<O>>::Archived, O, D>,
83{
84 fn deserialize_with(
85 field: &ArchivedOption<<A as ArchiveWith<O>>::Archived>,
86 d: &mut D,
87 ) -> Result<Option<O>, D::Error> {
88 match field {
89 ArchivedOption::Some(value) => Ok(Some(A::deserialize_with(value, d)?)),
90 ArchivedOption::None => Ok(None),
91 }
92 }
93}
94
95#[repr(u8)]
96enum ArchivedOptionTag {
97 None,
98 Some,
99}
100
101#[repr(C)]
102struct ArchivedOptionVariantNone(ArchivedOptionTag);
103
104#[repr(C)]
105struct ArchivedOptionVariantSome<T>(ArchivedOptionTag, T);
106
107impl<F: Archive> ArchiveWith<&F> for Inline {
110 type Archived = F::Archived;
111 type Resolver = F::Resolver;
112
113 #[inline]
114 unsafe fn resolve_with(
115 field: &&F,
116 pos: usize,
117 resolver: Self::Resolver,
118 out: *mut Self::Archived,
119 ) {
120 field.resolve(pos, resolver, out);
121 }
122}
123
124impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<&F, S> for Inline {
125 #[inline]
126 fn serialize_with(field: &&F, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
127 field.serialize(serializer)
128 }
129}
130
131impl<F: ArchiveUnsized + ?Sized> ArchiveWith<&F> for RefAsBox {
134 type Archived = ArchivedBox<F::Archived>;
135 type Resolver = BoxResolver<F::MetadataResolver>;
136
137 #[inline]
138 unsafe fn resolve_with(
139 field: &&F,
140 pos: usize,
141 resolver: Self::Resolver,
142 out: *mut Self::Archived,
143 ) {
144 ArchivedBox::resolve_from_ref(*field, pos, resolver, out);
145 }
146}
147
148impl<F: SerializeUnsized<S> + ?Sized, S: Fallible + ?Sized> SerializeWith<&F, S> for RefAsBox {
149 #[inline]
150 fn serialize_with(field: &&F, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
151 ArchivedBox::serialize_from_ref(*field, serializer)
152 }
153}
154
155impl<F: ArchiveUnsized + ?Sized> ArchiveWith<F> for AsBox {
158 type Archived = ArchivedBox<F::Archived>;
159 type Resolver = BoxResolver<F::MetadataResolver>;
160
161 #[inline]
162 unsafe fn resolve_with(
163 field: &F,
164 pos: usize,
165 resolver: Self::Resolver,
166 out: *mut Self::Archived,
167 ) {
168 ArchivedBox::resolve_from_ref(field, pos, resolver, out);
169 }
170}
171
172impl<F: SerializeUnsized<S> + ?Sized, S: Fallible + ?Sized> SerializeWith<F, S> for AsBox {
173 #[inline]
174 fn serialize_with(field: &F, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
175 ArchivedBox::serialize_from_ref(field, serializer)
176 }
177}
178
179impl<F: Archive, D: Fallible + ?Sized> DeserializeWith<ArchivedBox<F::Archived>, F, D> for AsBox
180where
181 F::Archived: Deserialize<F, D>,
182{
183 #[inline]
184 fn deserialize_with(
185 field: &ArchivedBox<F::Archived>,
186 deserializer: &mut D,
187 ) -> Result<F, D::Error> {
188 field.get().deserialize(deserializer)
189 }
190}
191
192macro_rules! impl_nonzero_niche {
195 ($ar:ty, $nz:ty, $ne:ty) => {
196 impl ArchiveWith<Option<$nz>> for Niche {
197 type Archived = $ar;
198 type Resolver = ();
199
200 #[inline]
201 unsafe fn resolve_with(
202 field: &Option<$nz>,
203 _: usize,
204 _: Self::Resolver,
205 out: *mut Self::Archived,
206 ) {
207 <$ar>::resolve_from_option(*field, out);
208 }
209 }
210
211 impl<S: Fallible + ?Sized> SerializeWith<Option<$nz>, S> for Niche {
212 #[inline]
213 fn serialize_with(_: &Option<$nz>, _: &mut S) -> Result<Self::Resolver, S::Error> {
214 Ok(())
215 }
216 }
217
218 impl<D: Fallible + ?Sized> DeserializeWith<$ar, Option<$nz>, D> for Niche {
219 #[inline]
220 fn deserialize_with(field: &$ar, _: &mut D) -> Result<Option<$nz>, D::Error> {
221 Ok(field.as_ref().map(|x| (*x).into()))
222 }
223 }
224 };
225}
226
227impl_nonzero_niche!(ArchivedOptionNonZeroI8, NonZeroI8, i8);
228impl_nonzero_niche!(ArchivedOptionNonZeroI16, NonZeroI16, i16);
229impl_nonzero_niche!(ArchivedOptionNonZeroI32, NonZeroI32, i32);
230impl_nonzero_niche!(ArchivedOptionNonZeroI64, NonZeroI64, i64);
231impl_nonzero_niche!(ArchivedOptionNonZeroI128, NonZeroI128, i128);
232
233type FixedNonZeroIsize = pick_size_type!(NonZeroI16, NonZeroI32, NonZeroI64);
234type ArchivedOptionNonZeroIsize = pick_size_type!(
235 ArchivedOptionNonZeroI16,
236 ArchivedOptionNonZeroI32,
237 ArchivedOptionNonZeroI64,
238);
239
240impl ArchiveWith<Option<NonZeroIsize>> for Niche {
241 type Archived = ArchivedOptionNonZeroIsize;
242 type Resolver = ();
243
244 #[inline]
245 unsafe fn resolve_with(
246 field: &Option<NonZeroIsize>,
247 _: usize,
248 _: Self::Resolver,
249 out: *mut Self::Archived,
250 ) {
251 let f = field.as_ref().map(|&x| x.try_into().unwrap());
252 ArchivedOptionNonZeroIsize::resolve_from_option(f, out);
253 }
254}
255
256impl<S: Fallible + ?Sized> SerializeWith<Option<NonZeroIsize>, S> for Niche {
257 #[inline]
258 fn serialize_with(_: &Option<NonZeroIsize>, _: &mut S) -> Result<Self::Resolver, S::Error> {
259 Ok(())
260 }
261}
262
263impl<D: Fallible + ?Sized> DeserializeWith<ArchivedOptionNonZeroIsize, Option<NonZeroIsize>, D>
264 for Niche
265{
266 #[inline]
267 fn deserialize_with(
268 field: &ArchivedOptionNonZeroIsize,
269 _: &mut D,
270 ) -> Result<Option<NonZeroIsize>, D::Error> {
271 #[allow(clippy::useless_conversion)]
273 Ok(field
274 .as_ref()
275 .map(|x| FixedNonZeroIsize::from(*x).try_into().unwrap()))
276 }
277}
278
279impl_nonzero_niche!(ArchivedOptionNonZeroU8, NonZeroU8, u8);
280impl_nonzero_niche!(ArchivedOptionNonZeroU16, NonZeroU16, u16);
281impl_nonzero_niche!(ArchivedOptionNonZeroU32, NonZeroU32, u32);
282impl_nonzero_niche!(ArchivedOptionNonZeroU64, NonZeroU64, u64);
283impl_nonzero_niche!(ArchivedOptionNonZeroU128, NonZeroU128, u128);
284
285type FixedNonZeroUsize = pick_size_type!(NonZeroU16, NonZeroU32, NonZeroU64);
286type ArchivedOptionNonZeroUsize = pick_size_type!(
287 ArchivedOptionNonZeroU16,
288 ArchivedOptionNonZeroU32,
289 ArchivedOptionNonZeroU64,
290);
291
292impl ArchiveWith<Option<NonZeroUsize>> for Niche {
293 type Archived = ArchivedOptionNonZeroUsize;
294 type Resolver = ();
295
296 #[inline]
297 unsafe fn resolve_with(
298 field: &Option<NonZeroUsize>,
299 _: usize,
300 _: Self::Resolver,
301 out: *mut Self::Archived,
302 ) {
303 let f = field.as_ref().map(|&x| x.try_into().unwrap());
304 ArchivedOptionNonZeroUsize::resolve_from_option(f, out);
305 }
306}
307
308impl<S: Fallible + ?Sized> SerializeWith<Option<NonZeroUsize>, S> for Niche {
309 #[inline]
310 fn serialize_with(_: &Option<NonZeroUsize>, _: &mut S) -> Result<Self::Resolver, S::Error> {
311 Ok(())
312 }
313}
314
315impl<D: Fallible + ?Sized> DeserializeWith<ArchivedOptionNonZeroUsize, Option<NonZeroUsize>, D>
316 for Niche
317{
318 #[inline]
319 fn deserialize_with(
320 field: &ArchivedOptionNonZeroUsize,
321 _: &mut D,
322 ) -> Result<Option<NonZeroUsize>, D::Error> {
323 #[allow(clippy::useless_conversion)]
325 Ok(field
326 .as_ref()
327 .map(|x| FixedNonZeroUsize::from(*x).try_into().unwrap()))
328 }
329}
330
331impl<F: Archive> ArchiveWith<UnsafeCell<F>> for Unsafe {
334 type Archived = UnsafeCell<F::Archived>;
335 type Resolver = F::Resolver;
336
337 #[inline]
338 unsafe fn resolve_with(
339 field: &UnsafeCell<F>,
340 pos: usize,
341 resolver: Self::Resolver,
342 out: *mut Self::Archived,
343 ) {
344 F::resolve(&*field.get(), pos, resolver, out.cast());
345 }
346}
347
348impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<UnsafeCell<F>, S> for Unsafe {
349 #[inline]
350 fn serialize_with(
351 field: &UnsafeCell<F>,
352 serializer: &mut S,
353 ) -> Result<Self::Resolver, S::Error> {
354 unsafe { (*field.get()).serialize(serializer) }
355 }
356}
357
358impl<F: Archive, D: Fallible + ?Sized> DeserializeWith<UnsafeCell<F::Archived>, UnsafeCell<F>, D>
359 for Unsafe
360where
361 F::Archived: Deserialize<F, D>,
362{
363 #[inline]
364 fn deserialize_with(
365 field: &UnsafeCell<F::Archived>,
366 deserializer: &mut D,
367 ) -> Result<UnsafeCell<F>, D::Error> {
368 unsafe {
369 (*field.get())
370 .deserialize(deserializer)
371 .map(|x| UnsafeCell::new(x))
372 }
373 }
374}
375
376impl<F: Archive> ArchiveWith<Cell<F>> for Unsafe {
377 type Archived = Cell<F::Archived>;
378 type Resolver = F::Resolver;
379
380 #[inline]
381 unsafe fn resolve_with(
382 field: &Cell<F>,
383 pos: usize,
384 resolver: Self::Resolver,
385 out: *mut Self::Archived,
386 ) {
387 F::resolve(&*field.as_ptr(), pos, resolver, out.cast());
388 }
389}
390
391impl<F: Serialize<S>, S: Fallible + ?Sized> SerializeWith<Cell<F>, S> for Unsafe {
392 #[inline]
393 fn serialize_with(field: &Cell<F>, serializer: &mut S) -> Result<Self::Resolver, S::Error> {
394 unsafe { (*field.as_ptr()).serialize(serializer) }
395 }
396}
397
398impl<F: Archive, D: Fallible + ?Sized> DeserializeWith<Cell<F::Archived>, Cell<F>, D> for Unsafe
399where
400 F::Archived: Deserialize<F, D>,
401{
402 #[inline]
403 fn deserialize_with(
404 field: &Cell<F::Archived>,
405 deserializer: &mut D,
406 ) -> Result<Cell<F>, D::Error> {
407 unsafe {
408 (*field.as_ptr())
409 .deserialize(deserializer)
410 .map(|x| Cell::new(x))
411 }
412 }
413}
414
415impl<F> ArchiveWith<F> for Skip {
418 type Archived = ();
419 type Resolver = ();
420
421 unsafe fn resolve_with(_: &F, _: usize, _: Self::Resolver, _: *mut Self::Archived) {}
422}
423
424impl<F, S: Fallible + ?Sized> SerializeWith<F, S> for Skip {
425 fn serialize_with(_: &F, _: &mut S) -> Result<(), S::Error> {
426 Ok(())
427 }
428}
429
430impl<F: Default, D: Fallible + ?Sized> DeserializeWith<(), F, D> for Skip {
431 fn deserialize_with(_: &(), _: &mut D) -> Result<F, D::Error> {
432 Ok(Default::default())
433 }
434}