aldrin_core/impls/
result.rs

1#[cfg(feature = "introspection")]
2use crate::introspection::{ir, Introspectable, LexicalId, References};
3use crate::tags::{PrimaryTag, Tag};
4use crate::{Deserialize, DeserializeError, Deserializer, Serialize, SerializeError, Serializer};
5use num_enum::{IntoPrimitive, TryFromPrimitive};
6
7impl<T: Tag, E: Tag> Tag for Result<T, E> {}
8
9impl<T: PrimaryTag, E: PrimaryTag> PrimaryTag for Result<T, E> {
10    type Tag = Result<T::Tag, E::Tag>;
11}
12
13#[derive(IntoPrimitive, TryFromPrimitive)]
14#[repr(u32)]
15enum ResultVariant {
16    Ok = 0,
17    Err = 1,
18}
19
20impl<T, U, E, F> Serialize<Result<T, E>> for Result<U, F>
21where
22    T: Tag,
23    U: Serialize<T>,
24    E: Tag,
25    F: Serialize<E>,
26{
27    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
28        match self {
29            Ok(value) => serializer.serialize_enum(ResultVariant::Ok, value),
30            Err(value) => serializer.serialize_enum(ResultVariant::Err, value),
31        }
32    }
33}
34
35impl<'a, T, U, E, F> Serialize<Result<T, E>> for &'a Result<U, F>
36where
37    T: Tag,
38    &'a U: Serialize<T>,
39    E: Tag,
40    &'a F: Serialize<E>,
41{
42    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
43        match self {
44            Ok(value) => serializer.serialize_enum(ResultVariant::Ok, value),
45            Err(value) => serializer.serialize_enum(ResultVariant::Err, value),
46        }
47    }
48}
49
50impl<T, U, E, F> Deserialize<Result<T, E>> for Result<U, F>
51where
52    T: Tag,
53    U: Deserialize<T>,
54    E: Tag,
55    F: Deserialize<E>,
56{
57    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
58        let deserializer = deserializer.deserialize_enum()?;
59
60        match deserializer.try_id()? {
61            ResultVariant::Ok => deserializer.deserialize().map(Ok),
62            ResultVariant::Err => deserializer.deserialize().map(Err),
63        }
64    }
65}
66
67#[cfg(feature = "introspection")]
68impl<T: Introspectable, E: Introspectable> Introspectable for Result<T, E> {
69    fn layout() -> ir::LayoutIr {
70        ir::BuiltInTypeIr::Result(ir::ResultTypeIr::new(T::lexical_id(), E::lexical_id())).into()
71    }
72
73    fn lexical_id() -> LexicalId {
74        LexicalId::result(T::lexical_id(), E::lexical_id())
75    }
76
77    fn add_references(references: &mut References) {
78        references.add::<T>();
79        references.add::<E>();
80    }
81}