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 #[track_caller]
50 pub fn unwrap(self) -> T::Surrogate {
51 self.0.unwrap().into_surrogate()
52 }
53
54 #[inline]
60 #[track_caller]
61 pub fn expect(self, msg: &StrSurrogate) -> T::Surrogate {
62 self.0.expect(&msg.0).into_surrogate()
63 }
64}
65
66impl_surrogate!({T} Option<T>, OptionSurrogate<T>);
67impl_surrogate_ref!({T} Option<T>, OptionSurrogate<T>);
68impl_surrogate_mut!({T} Option<T>, OptionSurrogate<T>);
69
70impl<T> serde::Serialize for OptionSurrogate<T>
71where
72 for<'a> &'a T: Surrogated,
73 for<'a> <&'a T as Surrogated>::Surrogate: serde::Serialize,
74{
75 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76 where
77 S: serde::Serializer,
78 {
79 let inner: Option<<&T as Surrogated>::Surrogate> =
80 self.0.as_ref().map(Surrogated::into_surrogate);
81 serialize_tagged(serializer, "Option", &inner)
82 }
83}
84
85impl<'de, T> serde::Deserialize<'de> for OptionSurrogate<T>
86where
87 T: Surrogated,
88 T::Surrogate: serde::Deserialize<'de>,
89{
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: serde::Deserializer<'de>,
93 {
94 let inner: Option<T::Surrogate> = deserialize_tagged(deserializer, "Option")?;
95 Ok(Self(inner.map(Surrogate::into_real)))
96 }
97}