Skip to main content

rustc_proc_macro/bridge/
rpc.rs

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