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