Skip to main content

topcoat_runtime/surrogate/
option.rs

1use ref_cast::RefCast;
2
3use crate::{
4    BoolSurrogate, StrSurrogate, Surrogate, Surrogated, deserialize_tagged, impl_surrogate,
5    impl_surrogate_mut, impl_surrogate_ref, serialize_tagged,
6};
7
8#[derive(Debug, Clone, RefCast)]
9#[repr(transparent)]
10pub struct OptionSurrogate<T>(Option<T>);
11
12impl<T> OptionSurrogate<T> {
13    #[inline]
14    pub(crate) const fn new(v: Option<T>) -> Self {
15        Self(v)
16    }
17
18    #[inline]
19    pub fn none() -> Self {
20        Self(None)
21    }
22
23    #[inline]
24    pub fn is_some(&self) -> BoolSurrogate {
25        BoolSurrogate::new(self.0.is_some())
26    }
27
28    #[inline]
29    pub fn is_none(&self) -> BoolSurrogate {
30        BoolSurrogate::new(self.0.is_none())
31    }
32}
33
34impl<T> OptionSurrogate<T>
35where
36    T: Surrogated,
37{
38    #[inline]
39    pub fn some(v: impl Surrogate<Real = T>) -> Self {
40        Self(Some(v.into_real()))
41    }
42
43    /// Returns the contained value.
44    ///
45    /// # Panics
46    ///
47    /// Panics if the option is `None`.
48    #[inline]
49    pub fn unwrap(self) -> T::Surrogate {
50        self.0.unwrap().into_surrogate()
51    }
52
53    /// Returns the contained value, panicking with `msg` if `None`.
54    ///
55    /// # Panics
56    ///
57    /// Panics with `msg` if the option is `None`.
58    #[inline]
59    pub fn expect(self, msg: &StrSurrogate) -> T::Surrogate {
60        self.0.expect(&msg.0).into_surrogate()
61    }
62}
63
64impl_surrogate!({T} Option<T>, OptionSurrogate<T>);
65impl_surrogate_ref!({T} Option<T>, OptionSurrogate<T>);
66impl_surrogate_mut!({T} Option<T>, OptionSurrogate<T>);
67
68impl<T> serde::Serialize for OptionSurrogate<T>
69where
70    for<'a> &'a T: Surrogated,
71    for<'a> <&'a T as Surrogated>::Surrogate: serde::Serialize,
72{
73    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74    where
75        S: serde::Serializer,
76    {
77        let inner: Option<<&T as Surrogated>::Surrogate> =
78            self.0.as_ref().map(Surrogated::into_surrogate);
79        serialize_tagged(serializer, "Option", &inner)
80    }
81}
82
83impl<'de, T> serde::Deserialize<'de> for OptionSurrogate<T>
84where
85    T: Surrogated,
86    T::Surrogate: serde::Deserialize<'de>,
87{
88    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
89    where
90        D: serde::Deserializer<'de>,
91    {
92        let inner: Option<T::Surrogate> = deserialize_tagged(deserializer, "Option")?;
93        Ok(Self(inner.map(Surrogate::into_real)))
94    }
95}