1 //! lib-proc-macro Serialization for client-server communication.
3 //! Copy from https://github.com/rust-lang/rust/blob/6050e523bae6de61de4e060facc43dc512adaccd/src/libproc_macro/bridge/rpc.rs
4 //! augmented with removing unstable features
6 //! Serialization for client-server communication.
11 use std::num::NonZeroU32;
15 pub(super) type Writer = super::buffer::Buffer<u8>;
17 pub(super) trait Encode<S>: Sized {
18 fn encode(self, w: &mut Writer, s: &mut S);
21 pub(super) type Reader<'a> = &'a [u8];
23 pub(super) trait Decode<'a, 's, S>: Sized {
24 fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
27 pub(super) trait DecodeMut<'a, 's, S>: Sized {
28 fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
31 macro_rules! rpc_encode_decode {
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();
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>();
43 let mut bytes = [0; N];
44 bytes.copy_from_slice(&r[..N]);
47 Self::from_le_bytes(bytes)
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);)*
58 impl<S> DecodeMut<'_, '_, S> for $name {
59 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
61 $($field: DecodeMut::decode(r, s)),*
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)]
73 #[repr(u8)] enum Tag { $($variant),* }
75 $(pub const $variant: u8 = Tag::$variant as u8;)*
79 $($name::$variant $(($field))* => {
80 tag::$variant.encode(w, s);
81 $($field.encode(w, s);)*
87 impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
88 for $name $(<$($T),+>)?
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)]
95 #[repr(u8)] enum Tag { $($variant),* }
97 $(pub const $variant: u8 = Tag::$variant as u8;)*
100 match u8::decode(r, s) {
102 $(let $field = DecodeMut::decode(r, s);)*
103 $name::$variant $(($field))*
112 impl<S> Encode<S> for () {
113 fn encode(self, _: &mut Writer, _: &mut S) {}
116 impl<S> DecodeMut<'_, '_, S> for () {
117 fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
120 impl<S> Encode<S> for u8 {
121 fn encode(self, w: &mut Writer, _: &mut S) {
122 w.write_all(&[self]).unwrap();
126 impl<S> DecodeMut<'_, '_, S> for u8 {
127 fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
134 rpc_encode_decode!(le u32);
135 rpc_encode_decode!(le usize);
137 impl<S> Encode<S> for bool {
138 fn encode(self, w: &mut Writer, s: &mut S) {
139 (self as u8).encode(w, s);
143 impl<S> DecodeMut<'_, '_, S> for bool {
144 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
145 match u8::decode(r, s) {
153 impl<S> Encode<S> for char {
154 fn encode(self, w: &mut Writer, s: &mut S) {
155 (self as u32).encode(w, s);
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()
165 impl<S> Encode<S> for NonZeroU32 {
166 fn encode(self, w: &mut Writer, s: &mut S) {
167 self.get().encode(w, s);
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()
177 impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
178 fn encode(self, w: &mut Writer, s: &mut S) {
184 impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
187 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
188 (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
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();
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);
230 impl<S> Encode<S> for &str {
231 fn encode(self, w: &mut Writer, s: &mut S) {
232 self.as_bytes().encode(w, s);
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()
242 impl<S> Encode<S> for String {
243 fn encode(self, w: &mut Writer, s: &mut S) {
244 self[..].encode(w, s);
248 impl<S> DecodeMut<'_, '_, S> for String {
249 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
250 <&str>::decode(r, s).to_string()
254 /// Simplied version of panic payloads, ignoring
255 /// types other than `&'static str` and `String`.
257 pub enum PanicMessage {
258 StaticStr(&'static str),
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);
268 if let Ok(s) = payload.downcast::<String>() {
269 return PanicMessage::String(*s);
271 PanicMessage::Unknown
275 impl Into<Box<dyn Any + Send>> for PanicMessage {
276 fn into(self) -> Box<dyn Any + Send> {
278 PanicMessage::StaticStr(s) => Box::new(s),
279 PanicMessage::String(s) => Box::new(s),
280 PanicMessage::Unknown => {
281 struct UnknownPanicMessage;
282 Box::new(UnknownPanicMessage)
289 pub fn as_str(&self) -> Option<&str> {
291 PanicMessage::StaticStr(s) => Some(s),
292 PanicMessage::String(s) => Some(s),
293 PanicMessage::Unknown => None,
298 impl<S> Encode<S> for PanicMessage {
299 fn encode(self, w: &mut Writer, s: &mut S) {
300 self.as_str().encode(w, s);
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,