Skip to main content

topcoat_runtime/surrogate/
result.rs

1use ref_cast::RefCast;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5    BoolSurrogate, OptionSurrogate, StrSurrogate, Surrogate, Surrogated, impl_surrogate,
6    impl_surrogate_mut, impl_surrogate_ref,
7};
8
9#[derive(Debug, Clone, RefCast)]
10#[repr(transparent)]
11pub struct ResultSurrogate<T, E>(Result<T, E>);
12
13impl<T, E> ResultSurrogate<T, E> {
14    #[inline]
15    pub(crate) const fn new(v: Result<T, E>) -> Self {
16        Self(v)
17    }
18
19    #[inline]
20    pub fn is_ok(&self) -> BoolSurrogate {
21        BoolSurrogate::new(self.0.is_ok())
22    }
23
24    #[inline]
25    pub fn is_err(&self) -> BoolSurrogate {
26        BoolSurrogate::new(self.0.is_err())
27    }
28
29    #[inline]
30    pub fn ok(self) -> OptionSurrogate<T> {
31        OptionSurrogate::new(self.0.ok())
32    }
33
34    #[inline]
35    pub fn err(self) -> OptionSurrogate<E> {
36        OptionSurrogate::new(self.0.err())
37    }
38}
39
40impl<T, E> ResultSurrogate<T, E> {
41    #[inline]
42    pub fn from_ok(v: impl Surrogate<Real = T>) -> Self {
43        Self(Result::Ok(v.into_real()))
44    }
45}
46
47impl<T, E> ResultSurrogate<T, E>
48where
49    T: Surrogated,
50    E: std::fmt::Debug,
51{
52    /// Returns the contained `Ok` value.
53    ///
54    /// # Panics
55    ///
56    /// Panics if the result is `Err`.
57    #[inline]
58    pub fn unwrap(self) -> T::Surrogate {
59        self.0.unwrap().into_surrogate()
60    }
61
62    /// Returns the contained `Ok` value, panicking with `msg` if `Err`.
63    ///
64    /// # Panics
65    ///
66    /// Panics with `msg` if the result is `Err`.
67    #[inline]
68    pub fn expect(self, msg: &StrSurrogate) -> T::Surrogate {
69        self.0.expect(&msg.0).into_surrogate()
70    }
71}
72
73impl<T, E> ResultSurrogate<T, E> {
74    #[inline]
75    pub fn from_err(v: impl Surrogate<Real = E>) -> Self {
76        Self(Result::Err(v.into_real()))
77    }
78}
79
80impl<T, E> ResultSurrogate<T, E>
81where
82    T: std::fmt::Debug,
83    E: Surrogated,
84{
85    #[inline]
86    pub fn unwrap_err(self) -> E::Surrogate {
87        self.0.unwrap_err().into_surrogate()
88    }
89
90    #[inline]
91    pub fn expect_err(self, msg: &StrSurrogate) -> E::Surrogate {
92        self.0.expect_err(&msg.to_string()).into_surrogate()
93    }
94}
95
96impl_surrogate!({T, E} Result<T, E>, ResultSurrogate<T, E>);
97impl_surrogate_ref!({T, E} Result<T, E>, ResultSurrogate<T, E>);
98impl_surrogate_mut!({T, E} Result<T, E>, ResultSurrogate<T, E>);
99
100#[derive(Serialize, Deserialize)]
101#[serde(untagged)]
102enum Body<T, E> {
103    Ok { t: String, ok: T },
104    Err { t: String, err: E },
105}
106
107impl<T, E> serde::Serialize for ResultSurrogate<T, E>
108where
109    for<'a> &'a T: Surrogated,
110    for<'a> <&'a T as Surrogated>::Surrogate: serde::Serialize,
111    for<'a> &'a E: Surrogated,
112    for<'a> <&'a E as Surrogated>::Surrogate: serde::Serialize,
113{
114    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
115    where
116        S: serde::Serializer,
117    {
118        let body = match &self.0 {
119            Result::Ok(v) => Body::Ok {
120                t: "Result".to_owned(),
121                ok: v.into_surrogate(),
122            },
123            Result::Err(e) => Body::Err {
124                t: "Result".to_owned(),
125                err: e.into_surrogate(),
126            },
127        };
128        body.serialize(serializer)
129    }
130}
131
132impl<'de, T, E> serde::Deserialize<'de> for ResultSurrogate<T, E>
133where
134    T: Surrogated,
135    T::Surrogate: serde::Deserialize<'de>,
136    E: Surrogated,
137    E::Surrogate: serde::Deserialize<'de>,
138{
139    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
140    where
141        D: serde::Deserializer<'de>,
142    {
143        let body = Body::<T::Surrogate, E::Surrogate>::deserialize(deserializer)?;
144        Ok(Self(match body {
145            Body::Ok { ok, .. } => Result::Ok(ok.into_real()),
146            Body::Err { err, .. } => Result::Err(err.into_real()),
147        }))
148    }
149}