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