1//! Serialization for client-server communication.
2
3use std::any::Any;
4use std::io::Write;
5use std::num::NonZero;
6use std::str;
7
8pub(super) type Writer = super::buffer::Buffer;
9
10pub(super) trait Encode<S>: Sized {
11 fn encode(self, w: &mut Writer, s: &mut S);
12}
13
14pub(super) type Reader<'a> = &'a [u8];
15
16pub(super) trait Decode<'a, 's, S>: Sized {
17 fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
18}
19
20pub(super) trait DecodeMut<'a, 's, S>: Sized {
21 fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
22}
23
24macro_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
107impl<S> Encode<S> for () {
108 fn encode(self, _: &mut Writer, _: &mut S) {}
109}
110
111impl<S> DecodeMut<'_, '_, S> for () {
112 fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
113}
114
115impl<S> Encode<S> for u8 {
116 fn encode(self, w: &mut Writer, _: &mut S) {
117 w.push(self);
118 }
119}
120
121impl<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
129rpc_encode_decode!(le u32);
130rpc_encode_decode!(le usize);
131
132impl<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
138impl<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
148impl<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
154impl<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
160impl<S> Encode<S> for NonZero<u32> {
161 fn encode(self, w: &mut Writer, s: &mut S) {
162 self.get().encode(w, s);
163 }
164}
165
166impl<S> DecodeMut<'_, '_, S> for NonZero<u32> {
167 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
168 Self::new(u32::decode(r, s)).unwrap()
169 }
170}
171
172impl<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
179impl<'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
187impl<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
194impl<'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
203impl<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
209impl<'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
215impl<S> Encode<S> for String {
216 fn encode(self, w: &mut Writer, s: &mut S) {
217 self[..].encode(w, s);
218 }
219}
220
221impl<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
227impl<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
236impl<'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`.
249pub enum PanicMessage {
250 StaticStr(&'static str),
251 String(String),
252 Unknown,
253}
254
255impl 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
267impl 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
280impl 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
290impl<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
296impl<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