]> git.proxmox.com Git - rustc.git/blob - library/proc_macro/src/bridge/rpc.rs
New upstream version 1.54.0+dfsg1
[rustc.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<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 (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 { $($field:ident),* $(,)? }) => {
47 impl<S> Encode<S> for $name {
48 fn encode(self, w: &mut Writer, s: &mut S) {
49 $(self.$field.encode(w, s);)*
50 }
51 }
52
53 impl<S> DecodeMut<'_, '_, S> for $name {
54 fn decode(r: &mut Reader<'_>, 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 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<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 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
107 impl<S> Encode<S> for () {
108 fn encode(self, _: &mut Writer, _: &mut S) {}
109 }
110
111 impl<S> DecodeMut<'_, '_, S> for () {
112 fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
113 }
114
115 impl<S> Encode<S> for u8 {
116 fn encode(self, w: &mut Writer, _: &mut S) {
117 w.push(self);
118 }
119 }
120
121 impl<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
129 rpc_encode_decode!(le u32);
130 rpc_encode_decode!(le usize);
131
132 impl<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
138 impl<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
148 impl<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
154 impl<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
160 impl<S> Encode<S> for NonZeroU32 {
161 fn encode(self, w: &mut Writer, s: &mut S) {
162 self.get().encode(w, s);
163 }
164 }
165
166 impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
167 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
168 Self::new(u32::decode(r, s)).unwrap()
169 }
170 }
171
172 impl<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
179 impl<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
187 rpc_encode_decode!(
188 enum Bound<T> {
189 Included(x),
190 Excluded(x),
191 Unbounded,
192 }
193 );
194
195 rpc_encode_decode!(
196 enum Option<T> {
197 None,
198 Some(x),
199 }
200 );
201
202 rpc_encode_decode!(
203 enum Result<T, E> {
204 Ok(x),
205 Err(e),
206 }
207 );
208
209 impl<S> Encode<S> for &[u8] {
210 fn encode(self, w: &mut Writer, s: &mut S) {
211 self.len().encode(w, s);
212 w.write_all(self).unwrap();
213 }
214 }
215
216 impl<S> DecodeMut<'a, '_, S> for &'a [u8] {
217 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
218 let len = usize::decode(r, s);
219 let xs = &r[..len];
220 *r = &r[len..];
221 xs
222 }
223 }
224
225 impl<S> Encode<S> for &str {
226 fn encode(self, w: &mut Writer, s: &mut S) {
227 self.as_bytes().encode(w, s);
228 }
229 }
230
231 impl<S> DecodeMut<'a, '_, S> for &'a str {
232 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
233 str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
234 }
235 }
236
237 impl<S> Encode<S> for String {
238 fn encode(self, w: &mut Writer, s: &mut S) {
239 self[..].encode(w, s);
240 }
241 }
242
243 impl<S> DecodeMut<'_, '_, S> for String {
244 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
245 <&str>::decode(r, s).to_string()
246 }
247 }
248
249 /// Simplied version of panic payloads, ignoring
250 /// types other than `&'static str` and `String`.
251 pub enum PanicMessage {
252 StaticStr(&'static str),
253 String(String),
254 Unknown,
255 }
256
257 impl From<Box<dyn Any + Send>> for PanicMessage {
258 fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
259 if let Some(s) = payload.downcast_ref::<&'static str>() {
260 return PanicMessage::StaticStr(s);
261 }
262 if let Ok(s) = payload.downcast::<String>() {
263 return PanicMessage::String(*s);
264 }
265 PanicMessage::Unknown
266 }
267 }
268
269 impl Into<Box<dyn Any + Send>> for PanicMessage {
270 fn into(self) -> Box<dyn Any + Send> {
271 match self {
272 PanicMessage::StaticStr(s) => Box::new(s),
273 PanicMessage::String(s) => Box::new(s),
274 PanicMessage::Unknown => {
275 struct UnknownPanicMessage;
276 Box::new(UnknownPanicMessage)
277 }
278 }
279 }
280 }
281
282 impl PanicMessage {
283 pub fn as_str(&self) -> Option<&str> {
284 match self {
285 PanicMessage::StaticStr(s) => Some(s),
286 PanicMessage::String(s) => Some(s),
287 PanicMessage::Unknown => None,
288 }
289 }
290 }
291
292 impl<S> Encode<S> for PanicMessage {
293 fn encode(self, w: &mut Writer, s: &mut S) {
294 self.as_str().encode(w, s);
295 }
296 }
297
298 impl<S> DecodeMut<'_, '_, S> for PanicMessage {
299 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
300 match Option::<String>::decode(r, s) {
301 Some(s) => PanicMessage::String(s),
302 None => PanicMessage::Unknown,
303 }
304 }
305 }