rkyv/impls/core/
result.rs1use core::hint::unreachable_unchecked;
2
3use munge::munge;
4use rancor::Fallible;
5
6use crate::{
7 result::ArchivedResult, traits::NoUndef, Archive, Deserialize, Place,
8 Serialize,
9};
10
11#[allow(dead_code)]
12#[repr(u8)]
13enum ArchivedResultTag {
14 Ok,
15 Err,
16}
17
18unsafe impl NoUndef for ArchivedResultTag {}
21
22#[repr(C)]
23struct ArchivedResultVariantOk<T>(ArchivedResultTag, T);
24
25#[repr(C)]
26struct ArchivedResultVariantErr<U>(ArchivedResultTag, U);
27
28impl<T: Archive, U: Archive> Archive for Result<T, U> {
29 type Archived = ArchivedResult<T::Archived, U::Archived>;
30 type Resolver = Result<T::Resolver, U::Resolver>;
31
32 fn resolve(&self, resolver: Self::Resolver, out: Place<Self::Archived>) {
33 match resolver {
34 Ok(resolver) => {
35 let out = unsafe {
36 out.cast_unchecked::<ArchivedResultVariantOk<T::Archived>>()
37 };
38 munge!(let ArchivedResultVariantOk(tag, out_value) = out);
39 tag.write(ArchivedResultTag::Ok);
40
41 match self.as_ref() {
42 Ok(value) => value.resolve(resolver, out_value),
43 Err(_) => unsafe { unreachable_unchecked() },
44 }
45 }
46 Err(resolver) => {
47 let out = unsafe {
48 out.cast_unchecked::<ArchivedResultVariantErr<U::Archived>>(
49 )
50 };
51 munge!(let ArchivedResultVariantErr(tag, out_err) = out);
52 tag.write(ArchivedResultTag::Err);
53
54 match self.as_ref() {
55 Ok(_) => unsafe { unreachable_unchecked() },
56 Err(err) => err.resolve(resolver, out_err),
57 }
58 }
59 }
60 }
61}
62
63impl<T, U, S> Serialize<S> for Result<T, U>
64where
65 T: Serialize<S>,
66 U: Serialize<S>,
67 S: Fallible + ?Sized,
68{
69 fn serialize(
70 &self,
71 serializer: &mut S,
72 ) -> Result<Self::Resolver, S::Error> {
73 Ok(match self.as_ref() {
74 Ok(value) => Ok(value.serialize(serializer)?),
75 Err(value) => Err(value.serialize(serializer)?),
76 })
77 }
78}
79
80impl<T, U, D> Deserialize<Result<T, U>, D>
81 for ArchivedResult<T::Archived, U::Archived>
82where
83 T: Archive,
84 U: Archive,
85 D: Fallible + ?Sized,
86 T::Archived: Deserialize<T, D>,
87 U::Archived: Deserialize<U, D>,
88{
89 fn deserialize(
90 &self,
91 deserializer: &mut D,
92 ) -> Result<Result<T, U>, D::Error> {
93 match self {
94 ArchivedResult::Ok(value) => {
95 Ok(Ok(value.deserialize(deserializer)?))
96 }
97 ArchivedResult::Err(err) => Ok(Err(err.deserialize(deserializer)?)),
98 }
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use crate::api::test::roundtrip;
105
106 #[test]
107 fn roundtrip_result() {
108 roundtrip(&Result::<i32, u32>::Ok(12345i32));
109 roundtrip(&Result::<i32, u32>::Err(12345u32));
110 }
111}