1 //! Serialization for client-server communication.
6 use std::num::NonZeroU32;
10 pub(super) type Writer = super::buffer::Buffer;
12 pub(super) trait Encode<S>: Sized {
13 fn encode(self, w: &mut Writer, s: &mut S);
16 pub(super) type Reader<'a> = &'a [u8];
18 pub(super) trait Decode<'a, 's, S>: Sized {
19 fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
22 pub(super) trait DecodeMut<'a, 's, S>: Sized {
23 fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
26 macro_rules! rpc_encode_decode {
28 impl<S> Encode<S> for $ty {
29 fn encode(self, w: &mut Writer, _: &mut S) {
30 w.extend_from_array(&self.to_le_bytes());
34 impl<S> DecodeMut<'_, '_, S> for $ty {
35 fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
36 const N: usize = ::std::mem::size_of::<$ty>();
38 let mut bytes = [0; N];
39 bytes.copy_from_slice(&r[..N]);
42 Self::from_le_bytes(bytes)
46 (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
47 impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
48 fn encode(self, w: &mut Writer, s: &mut S) {
49 $(self.$field.encode(w, s);)*
53 impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
54 for $name $(<$($T),+>)?
56 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
58 $($field: DecodeMut::decode(r, s)),*
63 (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
64 impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
65 fn encode(self, w: &mut Writer, s: &mut S) {
66 // HACK(eddyb): `Tag` enum duplicated between the
67 // two impls as there's no other place to stash it.
68 #[allow(non_upper_case_globals)]
70 #[repr(u8)] enum Tag { $($variant),* }
72 $(pub const $variant: u8 = Tag::$variant as u8;)*
76 $($name::$variant $(($field))* => {
77 tag::$variant.encode(w, s);
78 $($field.encode(w, s);)*
84 impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
85 for $name $(<$($T),+>)?
87 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
88 // HACK(eddyb): `Tag` enum duplicated between the
89 // two impls as there's no other place to stash it.
90 #[allow(non_upper_case_globals)]
92 #[repr(u8)] enum Tag { $($variant),* }
94 $(pub const $variant: u8 = Tag::$variant as u8;)*
97 match u8::decode(r, s) {
99 $(let $field = DecodeMut::decode(r, s);)*
100 $name::$variant $(($field))*
109 impl<S> Encode<S> for () {
110 fn encode(self, _: &mut Writer, _: &mut S) {}
113 impl<S> DecodeMut<'_, '_, S> for () {
114 fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
117 impl<S> Encode<S> for u8 {
118 fn encode(self, w: &mut Writer, _: &mut S) {
123 impl<S> DecodeMut<'_, '_, S> for u8 {
124 fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
131 rpc_encode_decode!(le u32);
132 rpc_encode_decode!(le usize);
134 impl<S> Encode<S> for bool {
135 fn encode(self, w: &mut Writer, s: &mut S) {
136 (self as u8).encode(w, s);
140 impl<S> DecodeMut<'_, '_, S> for bool {
141 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
142 match u8::decode(r, s) {
150 impl<S> Encode<S> for char {
151 fn encode(self, w: &mut Writer, s: &mut S) {
152 (self as u32).encode(w, s);
156 impl<S> DecodeMut<'_, '_, S> for char {
157 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
158 char::from_u32(u32::decode(r, s)).unwrap()
162 impl<S> Encode<S> for NonZeroU32 {
163 fn encode(self, w: &mut Writer, s: &mut S) {
164 self.get().encode(w, s);
168 impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
169 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
170 Self::new(u32::decode(r, s)).unwrap()
174 impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
175 fn encode(self, w: &mut Writer, s: &mut S) {
181 impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
184 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
185 (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
211 impl<S> Encode<S> for &[u8] {
212 fn encode(self, w: &mut Writer, s: &mut S) {
213 self.len().encode(w, s);
214 w.write_all(self).unwrap();
218 impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
219 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
220 let len = usize::decode(r, s);
227 impl<S> Encode<S> for &str {
228 fn encode(self, w: &mut Writer, s: &mut S) {
229 self.as_bytes().encode(w, s);
233 impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
234 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
235 str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
239 impl<S> Encode<S> for String {
240 fn encode(self, w: &mut Writer, s: &mut S) {
241 self[..].encode(w, s);
245 impl<S> DecodeMut<'_, '_, S> for String {
246 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
247 <&str>::decode(r, s).to_string()
251 impl<S, T: Encode<S>> Encode<S> for Vec<T> {
252 fn encode(self, w: &mut Writer, s: &mut S) {
253 self.len().encode(w, s);
260 impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
261 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
262 let len = usize::decode(r, s);
263 let mut vec = Vec::with_capacity(len);
265 vec.push(T::decode(r, s));
271 /// Simplified version of panic payloads, ignoring
272 /// types other than `&'static str` and `String`.
273 pub enum PanicMessage {
274 StaticStr(&'static str),
279 impl From<Box<dyn Any + Send>> for PanicMessage {
280 fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
281 if let Some(s) = payload.downcast_ref::<&'static str>() {
282 return PanicMessage::StaticStr(s);
284 if let Ok(s) = payload.downcast::<String>() {
285 return PanicMessage::String(*s);
287 PanicMessage::Unknown
291 impl Into<Box<dyn Any + Send>> for PanicMessage {
292 fn into(self) -> Box<dyn Any + Send> {
294 PanicMessage::StaticStr(s) => Box::new(s),
295 PanicMessage::String(s) => Box::new(s),
296 PanicMessage::Unknown => {
297 struct UnknownPanicMessage;
298 Box::new(UnknownPanicMessage)
305 pub fn as_str(&self) -> Option<&str> {
307 PanicMessage::StaticStr(s) => Some(s),
308 PanicMessage::String(s) => Some(s),
309 PanicMessage::Unknown => None,
314 impl<S> Encode<S> for PanicMessage {
315 fn encode(self, w: &mut Writer, s: &mut S) {
316 self.as_str().encode(w, s);
320 impl<S> DecodeMut<'_, '_, S> for PanicMessage {
321 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
322 match Option::<String>::decode(r, s) {
323 Some(s) => PanicMessage::String(s),
324 None => PanicMessage::Unknown,