Skip to main content

topcoat_runtime/
surrogate.rs

1mod _bool;
2mod _f64;
3mod _str;
4mod event;
5mod option;
6mod result;
7mod signal;
8mod string;
9mod tuple;
10
11use serde::{Deserialize, Serialize, de};
12
13pub use _bool::*;
14pub use _f64::*;
15pub use _str::*;
16pub use event::*;
17pub use option::*;
18pub use result::*;
19pub use signal::*;
20pub use string::*;
21
22pub trait Surrogated {
23    type Surrogate: Surrogate<Real = Self>;
24
25    fn into_surrogate(self) -> Self::Surrogate;
26}
27
28pub trait Surrogate {
29    type Real: Surrogated<Surrogate = Self>;
30
31    fn into_real(self) -> Self::Real;
32}
33
34#[macro_export]
35macro_rules! impl_surrogate {
36    (
37        $({$($g:tt)*})? $real:ty, $surrogate:ty
38        $(where $($w:tt)*)?
39    ) => {
40        impl<$($($g)*)?> $crate::Surrogated for $real
41        $(where $($w)*)?
42        {
43            type Surrogate = $surrogate;
44
45            fn into_surrogate(self) -> Self::Surrogate {
46                <$surrogate>::new(self)
47            }
48        }
49
50        impl<$($($g)*)?> $crate::Surrogate for $surrogate
51        $(where $($w)*)?
52        {
53            type Real = $real;
54
55            fn into_real(self) -> Self::Real {
56                self.0
57            }
58        }
59    };
60}
61
62#[macro_export]
63macro_rules! impl_surrogate_ref {
64    (
65        $({$($g:tt)*})? $real:ty, $surrogate:ty
66        $(where $($w:tt)*)?
67    ) => {
68        impl<'__lifetime, $($($g)*)?> $crate::Surrogated for &'__lifetime $real
69        $(where $($w)*)?
70        {
71            type Surrogate = &'__lifetime $surrogate;
72
73            fn into_surrogate(self) -> Self::Surrogate {
74                <$surrogate>::ref_cast(self)
75            }
76        }
77
78        impl<'__lifetime, $($($g)*)?> $crate::Surrogate for &'__lifetime $surrogate
79        $(where $($w)*)?
80        {
81            type Real = &'__lifetime $real;
82
83            fn into_real(self) -> Self::Real {
84                &self.0
85            }
86        }
87    };
88}
89
90#[macro_export]
91macro_rules! impl_surrogate_mut {
92    (
93        $({$($g:tt)*})? $real:ty, $surrogate:ty
94        $(where $($w:tt)*)?
95    ) => {
96        impl<'__lifetime, $($($g)*)?> $crate::Surrogated for &'__lifetime mut $real
97        $(where $($w)*)?
98        {
99            type Surrogate = &'__lifetime mut $surrogate;
100
101            fn into_surrogate(self) -> Self::Surrogate {
102                <$surrogate>::ref_cast_mut(self)
103            }
104        }
105
106        impl<'__lifetime, $($($g)*)?> $crate::Surrogate for &'__lifetime mut $surrogate
107        $(where $($w)*)?
108        {
109            type Real = &'__lifetime mut $real;
110
111            fn into_real(self) -> Self::Real {
112                &mut self.0
113            }
114        }
115    };
116}
117
118#[derive(Serialize)]
119struct TaggedRef<'a, T>
120where
121    T: ?Sized,
122{
123    t: &'static str,
124    v: &'a T,
125}
126
127#[derive(Deserialize)]
128#[serde(deny_unknown_fields)]
129struct Tagged<T> {
130    t: std::string::String,
131    v: T,
132}
133
134pub(crate) fn serialize_tagged<T, S>(
135    serializer: S,
136    tag: &'static str,
137    value: &T,
138) -> ::core::result::Result<S::Ok, S::Error>
139where
140    T: Serialize + ?Sized,
141    S: serde::Serializer,
142{
143    TaggedRef { t: tag, v: value }.serialize(serializer)
144}
145
146pub(crate) fn deserialize_tagged<'de, T, D>(
147    deserializer: D,
148    expected: &'static str,
149) -> ::core::result::Result<T, D::Error>
150where
151    T: Deserialize<'de>,
152    D: serde::Deserializer<'de>,
153{
154    let tagged = Tagged::<T>::deserialize(deserializer)?;
155    if tagged.t == expected {
156        Ok(tagged.v)
157    } else {
158        Err(de::Error::invalid_value(
159            de::Unexpected::Str(&tagged.t),
160            &expected,
161        ))
162    }
163}