1 | //! Serialization for client-server communication. |
2 | |
3 | use std::any::Any; |
4 | use std::io::Write; |
5 | use std::num::NonZeroU32; |
6 | use std::str; |
7 | |
8 | pub(super) type Writer = super::buffer::Buffer; |
9 | |
10 | pub(super) trait Encode<S>: Sized { |
11 | fn encode(self, w: &mut Writer, s: &mut S); |
12 | } |
13 | |
14 | pub(super) type Reader<'a> = &'a [u8]; |
15 | |
16 | pub(super) trait Decode<'a, 's, S>: Sized { |
17 | fn decode(r: &mut Reader<'a>, s: &'s S) -> Self; |
18 | } |
19 | |
20 | pub(super) trait DecodeMut<'a, 's, S>: Sized { |
21 | fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self; |
22 | } |
23 | |
24 | macro_rules! rpc_encode_decode { |
25 | (le $ty:ty) => { |
26 | impl<S> Encode<S> for $ty { |
27 | fn encode(self, w: &mut Writer, _: &mut S) { |
28 | w.extend_from_array(&self.to_le_bytes()); |
29 | } |
30 | } |
31 | |
32 | impl<S> DecodeMut<'_, '_, S> for $ty { |
33 | fn decode(r: &mut Reader<'_>, _: &mut S) -> Self { |
34 | const N: usize = ::std::mem::size_of::<$ty>(); |
35 | |
36 | let mut bytes = [0; N]; |
37 | bytes.copy_from_slice(&r[..N]); |
38 | *r = &r[N..]; |
39 | |
40 | Self::from_le_bytes(bytes) |
41 | } |
42 | } |
43 | }; |
44 | (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => { |
45 | impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? { |
46 | fn encode(self, w: &mut Writer, s: &mut S) { |
47 | $(self.$field.encode(w, s);)* |
48 | } |
49 | } |
50 | |
51 | impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S> |
52 | for $name $(<$($T),+>)? |
53 | { |
54 | fn decode(r: &mut Reader<'a>, 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<'a, 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: u8 = 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<'a, 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 | impl<S> Encode<S> for &[u8] { |
188 | fn encode(self, w: &mut Writer, s: &mut S) { |
189 | self.len().encode(w, s); |
190 | w.write_all(self).unwrap(); |
191 | } |
192 | } |
193 | |
194 | impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] { |
195 | fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { |
196 | let len: usize = usize::decode(r, s); |
197 | let xs: &[u8] = &r[..len]; |
198 | *r = &r[len..]; |
199 | xs |
200 | } |
201 | } |
202 | |
203 | impl<S> Encode<S> for &str { |
204 | fn encode(self, w: &mut Writer, s: &mut S) { |
205 | self.as_bytes().encode(w, s); |
206 | } |
207 | } |
208 | |
209 | impl<'a, S> DecodeMut<'a, '_, S> for &'a str { |
210 | fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { |
211 | str::from_utf8(<&[u8]>::decode(r, s)).unwrap() |
212 | } |
213 | } |
214 | |
215 | impl<S> Encode<S> for String { |
216 | fn encode(self, w: &mut Writer, s: &mut S) { |
217 | self[..].encode(w, s); |
218 | } |
219 | } |
220 | |
221 | impl<S> DecodeMut<'_, '_, S> for String { |
222 | fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { |
223 | <&str>::decode(r, s).to_string() |
224 | } |
225 | } |
226 | |
227 | impl<S, T: Encode<S>> Encode<S> for Vec<T> { |
228 | fn encode(self, w: &mut Writer, s: &mut S) { |
229 | self.len().encode(w, s); |
230 | for x: T in self { |
231 | x.encode(w, s); |
232 | } |
233 | } |
234 | } |
235 | |
236 | impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> { |
237 | fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { |
238 | let len: usize = usize::decode(r, s); |
239 | let mut vec: Vec = Vec::with_capacity(len); |
240 | for _ in 0..len { |
241 | vec.push(T::decode(r, s)); |
242 | } |
243 | vec |
244 | } |
245 | } |
246 | |
247 | /// Simplified version of panic payloads, ignoring |
248 | /// types other than `&'static str` and `String`. |
249 | pub enum PanicMessage { |
250 | StaticStr(&'static str), |
251 | String(String), |
252 | Unknown, |
253 | } |
254 | |
255 | impl From<Box<dyn Any + Send>> for PanicMessage { |
256 | fn from(payload: Box<dyn Any + Send + 'static>) -> Self { |
257 | if let Some(s: &&str) = payload.downcast_ref::<&'static str>() { |
258 | return PanicMessage::StaticStr(s); |
259 | } |
260 | if let Ok(s: Box) = payload.downcast::<String>() { |
261 | return PanicMessage::String(*s); |
262 | } |
263 | PanicMessage::Unknown |
264 | } |
265 | } |
266 | |
267 | impl Into<Box<dyn Any + Send>> for PanicMessage { |
268 | fn into(self) -> Box<dyn Any + Send> { |
269 | match self { |
270 | PanicMessage::StaticStr(s: &str) => Box::new(s), |
271 | PanicMessage::String(s: String) => Box::new(s), |
272 | PanicMessage::Unknown => { |
273 | struct UnknownPanicMessage; |
274 | Box::new(UnknownPanicMessage) |
275 | } |
276 | } |
277 | } |
278 | } |
279 | |
280 | impl PanicMessage { |
281 | pub fn as_str(&self) -> Option<&str> { |
282 | match self { |
283 | PanicMessage::StaticStr(s: &&str) => Some(s), |
284 | PanicMessage::String(s: &String) => Some(s), |
285 | PanicMessage::Unknown => None, |
286 | } |
287 | } |
288 | } |
289 | |
290 | impl<S> Encode<S> for PanicMessage { |
291 | fn encode(self, w: &mut Writer, s: &mut S) { |
292 | self.as_str().encode(w, s); |
293 | } |
294 | } |
295 | |
296 | impl<S> DecodeMut<'_, '_, S> for PanicMessage { |
297 | fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { |
298 | match Option::<String>::decode(r, s) { |
299 | Some(s: String) => PanicMessage::String(s), |
300 | None => PanicMessage::Unknown, |
301 | } |
302 | } |
303 | } |
304 | |