]> git.lizzy.rs Git - rust.git/blob - library/proc_macro/src/bridge/rpc.rs
Specialize single-element writes to buffer
[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<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.write_all(&self.to_le_bytes()).unwrap();
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 }