topcoat_runtime/surrogate/
option.rs1use 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 #[inline]
49 pub fn unwrap(self) -> T::Surrogate {
50 self.0.unwrap().into_surrogate()
51 }
52
53 #[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}