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