Skip to main content

rustc_proc_macro/bridge/
rpc.rs

1//! Serialization for client-server communication.
2
3use std::io::Write;
4use std::num::NonZero;
5
6use super::buffer::Buffer;
7
8pub(super) trait Encode<S>: Sized {
9    fn encode(self, w: &mut Buffer, s: &mut S);
10}
11
12pub(super) trait Decode<'a, 's, S>: Sized {
13    fn decode(r: &mut &'a [u8], s: &'s mut S) -> Self;
14}
15
16macro_rules! rpc_encode_decode {
17    (le $ty:ty) => {
18        impl<S> Encode<S> for $ty {
19            #[inline]
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            #[inline]
27            fn decode(r: &mut &[u8], _: &mut S) -> Self {
28                const N: usize = size_of::<$ty>();
29
30                let mut bytes = [0; N];
31                bytes.copy_from_slice(&r[..N]);
32                *r = &r[N..];
33
34                Self::from_le_bytes(bytes)
35            }
36        }
37    };
38    (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
39        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
40            fn encode(self, w: &mut Buffer, s: &mut S) {
41                $(self.$field.encode(w, s);)*
42            }
43        }
44
45        impl<'a, S, $($($T: for<'s> Decode<'a, 's, S>),+)?> Decode<'a, '_, S>
46            for $name $(<$($T),+>)?
47        {
48            #[inline]
49            fn decode(r: &mut &'a [u8], s: &mut S) -> Self {
50                $name {
51                    $($field: Decode::decode(r, s)),*
52                }
53            }
54        }
55    };
56    (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
57        #[allow(non_upper_case_globals, non_camel_case_types)]
58        const _: () = {
59            #[repr(u8)] enum Tag { $($variant),* }
60
61            $(const $variant: u8 = Tag::$variant as u8;)*
62
63            impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
64                #[inline]
65                fn encode(self, w: &mut Buffer, s: &mut S) {
66                    match self {
67                        $($name::$variant $(($field))* => {
68                            $variant.encode(w, s);
69                            $($field.encode(w, s);)*
70                        })*
71                    }
72                }
73            }
74
75            impl<'a, S, $($($T: for<'s> Decode<'a, 's, S>),+)?> Decode<'a, '_, S>
76                for $name $(<$($T),+>)?
77            {
78                #[inline]
79                fn decode(r: &mut &'a [u8], s: &mut S) -> Self {
80                    match u8::decode(r, s) {
81                        $($variant => {
82                            $(let $field = Decode::decode(r, s);)*
83                            $name::$variant $(($field))*
84                        })*
85                        _ => unreachable!(),
86                    }
87                }
88            }
89        };
90    }
91}
92
93impl<S> Encode<S> for () {
94    #[inline]
95    fn encode(self, _: &mut Buffer, _: &mut S) {}
96}
97
98impl<S> Decode<'_, '_, S> for () {
99    #[inline]
100    fn decode(_: &mut &[u8], _: &mut S) -> Self {}
101}
102
103impl<S> Encode<S> for u8 {
104    #[inline]
105    fn encode(self, w: &mut Buffer, _: &mut S) {
106        w.push(self);
107    }
108}
109
110impl<S> Decode<'_, '_, S> for u8 {
111    #[inline]
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 {
    #[inline]
    fn encode(self, w: &mut Buffer, _: &mut S) {
        w.extend_from_array(&self.to_le_bytes());
    }
}
impl<S> Decode<'_, '_, S> for u32 {
    #[inline]
    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);
120#[cfg(target_pointer_width = "64")]
121impl<S> Encode<S> for usize {
    #[inline]
    fn encode(self, w: &mut Buffer, _: &mut S) {
        w.extend_from_array(&self.to_le_bytes());
    }
}
impl<S> Decode<'_, '_, S> for usize {
    #[inline]
    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);
122
123#[cfg(not(target_pointer_width = "64"))]
124const MAX_USIZE_SIZE: usize = 8;
125
126#[cfg(not(target_pointer_width = "64"))]
127impl<S> Encode<S> for usize {
128    #[inline]
129    fn encode(self, w: &mut Buffer, _: &mut S) {
130        const N: usize = size_of::<usize>();
131
132        // We can pad with zeros without changing the value because of
133        // little endian encoding.
134        let mut bytes = [0; MAX_USIZE_SIZE];
135        bytes[..N].copy_from_slice(&self.to_le_bytes());
136
137        w.extend_from_array(&bytes);
138    }
139}
140
141#[cfg(not(target_pointer_width = "64"))]
142impl<S> Decode<'_, '_, S> for usize {
143    #[inline]
144    fn decode(r: &mut &[u8], _: &mut S) -> Self {
145        const N: usize = size_of::<usize>();
146        const {
147            assert!(N <= MAX_USIZE_SIZE);
148        }
149
150        let mut bytes = [0; N];
151        bytes.copy_from_slice(&r[..N]);
152        *r = &r[MAX_USIZE_SIZE..];
153
154        Self::from_le_bytes(bytes)
155    }
156}
157
158impl<S> Encode<S> for bool {
159    #[inline]
160    fn encode(self, w: &mut Buffer, s: &mut S) {
161        (self as u8).encode(w, s);
162    }
163}
164
165impl<S> Decode<'_, '_, S> for bool {
166    #[inline]
167    fn decode(r: &mut &[u8], s: &mut S) -> Self {
168        match u8::decode(r, s) {
169            0 => false,
170            1 => true,
171            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
172        }
173    }
174}
175
176impl<S> Encode<S> for NonZero<u32> {
177    #[inline]
178    fn encode(self, w: &mut Buffer, s: &mut S) {
179        self.get().encode(w, s);
180    }
181}
182
183impl<S> Decode<'_, '_, S> for NonZero<u32> {
184    #[inline]
185    fn decode(r: &mut &[u8], s: &mut S) -> Self {
186        Self::new(u32::decode(r, s)).unwrap()
187    }
188}
189
190impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
191    #[inline]
192    fn encode(self, w: &mut Buffer, s: &mut S) {
193        self.0.encode(w, s);
194        self.1.encode(w, s);
195    }
196}
197
198impl<'a, S, A: for<'s> Decode<'a, 's, S>, B: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S>
199    for (A, B)
200{
201    #[inline]
202    fn decode(r: &mut &'a [u8], s: &mut S) -> Self {
203        (Decode::decode(r, s), Decode::decode(r, s))
204    }
205}
206
207impl<S> Encode<S> for &str {
208    #[inline]
209    fn encode(self, w: &mut Buffer, s: &mut S) {
210        let bytes = self.as_bytes();
211        bytes.len().encode(w, s);
212        w.write_all(bytes).unwrap();
213    }
214}
215
216impl<'a, S> Decode<'a, '_, S> for &'a str {
217    #[inline]
218    fn decode(r: &mut &'a [u8], s: &mut S) -> Self {
219        let len = usize::decode(r, s);
220        let xs = &r[..len];
221        *r = &r[len..];
222        str::from_utf8(xs).unwrap()
223    }
224}
225
226impl<S> Encode<S> for String {
227    #[inline]
228    fn encode(self, w: &mut Buffer, s: &mut S) {
229        self[..].encode(w, s);
230    }
231}
232
233impl<S> Decode<'_, '_, S> for String {
234    #[inline]
235    fn decode(r: &mut &[u8], s: &mut S) -> Self {
236        <&str>::decode(r, s).to_string()
237    }
238}
239
240impl<S, T: Encode<S>> Encode<S> for Vec<T> {
241    #[inline]
242    fn encode(self, w: &mut Buffer, s: &mut S) {
243        self.len().encode(w, s);
244        for x in self {
245            x.encode(w, s);
246        }
247    }
248}
249
250impl<'a, S, T: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> for Vec<T> {
251    #[inline]
252    fn decode(r: &mut &'a [u8], s: &mut S) -> Self {
253        let len = usize::decode(r, s);
254        let mut vec = Vec::with_capacity(len);
255        for _ in 0..len {
256            vec.push(T::decode(r, s));
257        }
258        vec
259    }
260}