proc_macro/bridge/
rpc.rs

1//! Serialization for client-server communication.
2
3use std::any::Any;
4use std::io::Write;
5use std::num::NonZero;
6
7pub(super) type Writer = super::buffer::Buffer;
8
9pub(super) trait Encode<S>: Sized {
10    fn encode(self, w: &mut Writer, s: &mut S);
11}
12
13pub(super) type Reader<'a> = &'a [u8];
14
15pub(super) trait DecodeMut<'a, 's, S>: Sized {
16    fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
17}
18
19macro_rules! rpc_encode_decode {
20    (le $ty:ty) => {
21        impl<S> Encode<S> for $ty {
22            fn encode(self, w: &mut Writer, _: &mut S) {
23                w.extend_from_array(&self.to_le_bytes());
24            }
25        }
26
27        impl<S> DecodeMut<'_, '_, S> for $ty {
28            fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
29                const N: usize = size_of::<$ty>();
30
31                let mut bytes = [0; N];
32                bytes.copy_from_slice(&r[..N]);
33                *r = &r[N..];
34
35                Self::from_le_bytes(bytes)
36            }
37        }
38    };
39    (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
40        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
41            fn encode(self, w: &mut Writer, s: &mut S) {
42                $(self.$field.encode(w, s);)*
43            }
44        }
45
46        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
47            for $name $(<$($T),+>)?
48        {
49            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
50                $name {
51                    $($field: DecodeMut::decode(r, s)),*
52                }
53            }
54        }
55    };
56    (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
57        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
58            fn encode(self, w: &mut Writer, s: &mut S) {
59                // HACK(eddyb): `Tag` enum duplicated between the
60                // two impls as there's no other place to stash it.
61                #[allow(non_upper_case_globals)]
62                mod tag {
63                    #[repr(u8)] enum Tag { $($variant),* }
64
65                    $(pub(crate) const $variant: u8 = Tag::$variant as u8;)*
66                }
67
68                match self {
69                    $($name::$variant $(($field))* => {
70                        tag::$variant.encode(w, s);
71                        $($field.encode(w, s);)*
72                    })*
73                }
74            }
75        }
76
77        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
78            for $name $(<$($T),+>)?
79        {
80            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
81                // HACK(eddyb): `Tag` enum duplicated between the
82                // two impls as there's no other place to stash it.
83                #[allow(non_upper_case_globals)]
84                mod tag {
85                    #[repr(u8)] enum Tag { $($variant),* }
86
87                    $(pub(crate) const $variant: u8 = Tag::$variant as u8;)*
88                }
89
90                match u8::decode(r, s) {
91                    $(tag::$variant => {
92                        $(let $field = DecodeMut::decode(r, s);)*
93                        $name::$variant $(($field))*
94                    })*
95                    _ => unreachable!(),
96                }
97            }
98        }
99    }
100}
101
102impl<S> Encode<S> for () {
103    fn encode(self, _: &mut Writer, _: &mut S) {}
104}
105
106impl<S> DecodeMut<'_, '_, S> for () {
107    fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
108}
109
110impl<S> Encode<S> for u8 {
111    fn encode(self, w: &mut Writer, _: &mut S) {
112        w.push(self);
113    }
114}
115
116impl<S> DecodeMut<'_, '_, S> for u8 {
117    fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
118        let x = r[0];
119        *r = &r[1..];
120        x
121    }
122}
123
124rpc_encode_decode!(le u32);
125rpc_encode_decode!(le usize);
126
127impl<S> Encode<S> for bool {
128    fn encode(self, w: &mut Writer, s: &mut S) {
129        (self as u8).encode(w, s);
130    }
131}
132
133impl<S> DecodeMut<'_, '_, S> for bool {
134    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
135        match u8::decode(r, s) {
136            0 => false,
137            1 => true,
138            _ => unreachable!(),
139        }
140    }
141}
142
143impl<S> Encode<S> for char {
144    fn encode(self, w: &mut Writer, s: &mut S) {
145        (self as u32).encode(w, s);
146    }
147}
148
149impl<S> DecodeMut<'_, '_, S> for char {
150    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
151        char::from_u32(u32::decode(r, s)).unwrap()
152    }
153}
154
155impl<S> Encode<S> for NonZero<u32> {
156    fn encode(self, w: &mut Writer, s: &mut S) {
157        self.get().encode(w, s);
158    }
159}
160
161impl<S> DecodeMut<'_, '_, S> for NonZero<u32> {
162    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
163        Self::new(u32::decode(r, s)).unwrap()
164    }
165}
166
167impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
168    fn encode(self, w: &mut Writer, s: &mut S) {
169        self.0.encode(w, s);
170        self.1.encode(w, s);
171    }
172}
173
174impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
175    for (A, B)
176{
177    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
178        (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
179    }
180}
181
182impl<S> Encode<S> for &[u8] {
183    fn encode(self, w: &mut Writer, s: &mut S) {
184        self.len().encode(w, s);
185        w.write_all(self).unwrap();
186    }
187}
188
189impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
190    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
191        let len = usize::decode(r, s);
192        let xs = &r[..len];
193        *r = &r[len..];
194        xs
195    }
196}
197
198impl<S> Encode<S> for &str {
199    fn encode(self, w: &mut Writer, s: &mut S) {
200        self.as_bytes().encode(w, s);
201    }
202}
203
204impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
205    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
206        str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
207    }
208}
209
210impl<S> Encode<S> for String {
211    fn encode(self, w: &mut Writer, s: &mut S) {
212        self[..].encode(w, s);
213    }
214}
215
216impl<S> DecodeMut<'_, '_, S> for String {
217    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
218        <&str>::decode(r, s).to_string()
219    }
220}
221
222impl<S, T: Encode<S>> Encode<S> for Vec<T> {
223    fn encode(self, w: &mut Writer, s: &mut S) {
224        self.len().encode(w, s);
225        for x in self {
226            x.encode(w, s);
227        }
228    }
229}
230
231impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
232    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
233        let len = usize::decode(r, s);
234        let mut vec = Vec::with_capacity(len);
235        for _ in 0..len {
236            vec.push(T::decode(r, s));
237        }
238        vec
239    }
240}
241
242/// Simplified version of panic payloads, ignoring
243/// types other than `&'static str` and `String`.
244pub enum PanicMessage {
245    StaticStr(&'static str),
246    String(String),
247    Unknown,
248}
249
250impl From<Box<dyn Any + Send>> for PanicMessage {
251    fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
252        if let Some(s) = payload.downcast_ref::<&'static str>() {
253            return PanicMessage::StaticStr(s);
254        }
255        if let Ok(s) = payload.downcast::<String>() {
256            return PanicMessage::String(*s);
257        }
258        PanicMessage::Unknown
259    }
260}
261
262impl From<PanicMessage> for Box<dyn Any + Send> {
263    fn from(val: PanicMessage) -> Self {
264        match val {
265            PanicMessage::StaticStr(s) => Box::new(s),
266            PanicMessage::String(s) => Box::new(s),
267            PanicMessage::Unknown => {
268                struct UnknownPanicMessage;
269                Box::new(UnknownPanicMessage)
270            }
271        }
272    }
273}
274
275impl PanicMessage {
276    pub fn as_str(&self) -> Option<&str> {
277        match self {
278            PanicMessage::StaticStr(s) => Some(s),
279            PanicMessage::String(s) => Some(s),
280            PanicMessage::Unknown => None,
281        }
282    }
283}
284
285impl<S> Encode<S> for PanicMessage {
286    fn encode(self, w: &mut Writer, s: &mut S) {
287        self.as_str().encode(w, s);
288    }
289}
290
291impl<S> DecodeMut<'_, '_, S> for PanicMessage {
292    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
293        match Option::<String>::decode(r, s) {
294            Some(s) => PanicMessage::String(s),
295            None => PanicMessage::Unknown,
296        }
297    }
298}