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