aboutsummaryrefslogtreecommitdiff
path: root/crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs')
-rw-r--r--crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs311
1 files changed, 311 insertions, 0 deletions
diff --git a/crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs b/crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs
new file mode 100644
index 000000000..3528d5c99
--- /dev/null
+++ b/crates/proc_macro_srv/src/proc_macro/bridge/rpc.rs
@@ -0,0 +1,311 @@
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
8use std::any::Any;
9use std::char;
10use std::io::Write;
11use std::num::NonZeroU32;
12use std::ops::Bound;
13use std::str;
14
15pub(super) type Writer = super::buffer::Buffer<u8>;
16
17pub(super) trait Encode<S>: Sized {
18 fn encode(self, w: &mut Writer, s: &mut S);
19}
20
21pub(super) type Reader<'a> = &'a [u8];
22
23pub(super) trait Decode<'a, 's, S>: Sized {
24 fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
25}
26
27pub(super) trait DecodeMut<'a, 's, S>: Sized {
28 fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
29}
30
31macro_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
112impl<S> Encode<S> for () {
113 fn encode(self, _: &mut Writer, _: &mut S) {}
114}
115
116impl<S> DecodeMut<'_, '_, S> for () {
117 fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
118}
119
120impl<S> Encode<S> for u8 {
121 fn encode(self, w: &mut Writer, _: &mut S) {
122 w.write_all(&[self]).unwrap();
123 }
124}
125
126impl<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
134rpc_encode_decode!(le u32);
135rpc_encode_decode!(le usize);
136
137impl<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
143impl<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
153impl<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
159impl<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
165impl<S> Encode<S> for NonZeroU32 {
166 fn encode(self, w: &mut Writer, s: &mut S) {
167 self.get().encode(w, s);
168 }
169}
170
171impl<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
177impl<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
184impl<'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
192rpc_encode_decode!(
193 enum Bound<T> {
194 Included(x),
195 Excluded(x),
196 Unbounded,
197 }
198);
199
200rpc_encode_decode!(
201 enum Option<T> {
202 None,
203 Some(x),
204 }
205);
206
207rpc_encode_decode!(
208 enum Result<T, E> {
209 Ok(x),
210 Err(e),
211 }
212);
213
214impl<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
221impl<'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
230impl<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
236impl<'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
242impl<S> Encode<S> for String {
243 fn encode(self, w: &mut Writer, s: &mut S) {
244 self[..].encode(w, s);
245 }
246}
247
248impl<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/// Simplied version of panic payloads, ignoring
255/// types other than `&'static str` and `String`.
256#[derive(Debug)]
257pub enum PanicMessage {
258 StaticStr(&'static str),
259 String(String),
260 Unknown,
261}
262
263impl 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
275impl 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
288impl 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
298impl<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
304impl<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}