proc_macro/bridge/
rpc.rs

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