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