1 //! Serialization for client-server communication.
6 use std::num::NonZeroU32;
9 pub(super) type Writer = super::buffer::Buffer;
11 pub(super) trait Encode<S>: Sized {
12 fn encode(self, w: &mut Writer, s: &mut S);
15 pub(super) type Reader<'a> = &'a [u8];
17 pub(super) trait Decode<'a, 's, S>: Sized {
18 fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
21 pub(super) trait DecodeMut<'a, 's, S>: Sized {
22 fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
25 macro_rules! rpc_encode_decode {
27 impl<S> Encode<S> for $ty {
28 fn encode(self, w: &mut Writer, _: &mut S) {
29 w.extend_from_array(&self.to_le_bytes());
33 impl<S> DecodeMut<'_, '_, S> for $ty {
34 fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
35 const N: usize = ::std::mem::size_of::<$ty>();
37 let mut bytes = [0; N];
38 bytes.copy_from_slice(&r[..N]);
41 Self::from_le_bytes(bytes)
45 (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
46 impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
47 fn encode(self, w: &mut Writer, s: &mut S) {
48 $(self.$field.encode(w, s);)*
52 impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
53 for $name $(<$($T),+>)?
55 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
57 $($field: DecodeMut::decode(r, s)),*
62 (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
63 impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
64 fn encode(self, w: &mut Writer, s: &mut S) {
65 // HACK(eddyb): `Tag` enum duplicated between the
66 // two impls as there's no other place to stash it.
67 #[allow(non_upper_case_globals)]
69 #[repr(u8)] enum Tag { $($variant),* }
71 $(pub const $variant: u8 = Tag::$variant as u8;)*
75 $($name::$variant $(($field))* => {
76 tag::$variant.encode(w, s);
77 $($field.encode(w, s);)*
83 impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
84 for $name $(<$($T),+>)?
86 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
87 // HACK(eddyb): `Tag` enum duplicated between the
88 // two impls as there's no other place to stash it.
89 #[allow(non_upper_case_globals)]
91 #[repr(u8)] enum Tag { $($variant),* }
93 $(pub const $variant: u8 = Tag::$variant as u8;)*
96 match u8::decode(r, s) {
98 $(let $field = DecodeMut::decode(r, s);)*
99 $name::$variant $(($field))*
108 impl<S> Encode<S> for () {
109 fn encode(self, _: &mut Writer, _: &mut S) {}
112 impl<S> DecodeMut<'_, '_, S> for () {
113 fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
116 impl<S> Encode<S> for u8 {
117 fn encode(self, w: &mut Writer, _: &mut S) {
122 impl<S> DecodeMut<'_, '_, S> for u8 {
123 fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
130 rpc_encode_decode!(le u32);
131 rpc_encode_decode!(le usize);
133 impl<S> Encode<S> for bool {
134 fn encode(self, w: &mut Writer, s: &mut S) {
135 (self as u8).encode(w, s);
139 impl<S> DecodeMut<'_, '_, S> for bool {
140 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
141 match u8::decode(r, s) {
149 impl<S> Encode<S> for char {
150 fn encode(self, w: &mut Writer, s: &mut S) {
151 (self as u32).encode(w, s);
155 impl<S> DecodeMut<'_, '_, S> for char {
156 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
157 char::from_u32(u32::decode(r, s)).unwrap()
161 impl<S> Encode<S> for NonZeroU32 {
162 fn encode(self, w: &mut Writer, s: &mut S) {
163 self.get().encode(w, s);
167 impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
168 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
169 Self::new(u32::decode(r, s)).unwrap()
173 impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
174 fn encode(self, w: &mut Writer, s: &mut S) {
180 impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
183 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
184 (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
188 impl<S> Encode<S> for &[u8] {
189 fn encode(self, w: &mut Writer, s: &mut S) {
190 self.len().encode(w, s);
191 w.write_all(self).unwrap();
195 impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
196 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
197 let len = usize::decode(r, s);
204 impl<S> Encode<S> for &str {
205 fn encode(self, w: &mut Writer, s: &mut S) {
206 self.as_bytes().encode(w, s);
210 impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
211 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
212 str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
216 impl<S> Encode<S> for String {
217 fn encode(self, w: &mut Writer, s: &mut S) {
218 self[..].encode(w, s);
222 impl<S> DecodeMut<'_, '_, S> for String {
223 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
224 <&str>::decode(r, s).to_string()
228 impl<S, T: Encode<S>> Encode<S> for Vec<T> {
229 fn encode(self, w: &mut Writer, s: &mut S) {
230 self.len().encode(w, s);
237 impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
238 fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
239 let len = usize::decode(r, s);
240 let mut vec = Vec::with_capacity(len);
242 vec.push(T::decode(r, s));
248 /// Simplified version of panic payloads, ignoring
249 /// types other than `&'static str` and `String`.
250 pub enum PanicMessage {
251 StaticStr(&'static str),
256 impl From<Box<dyn Any + Send>> for PanicMessage {
257 fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
258 if let Some(s) = payload.downcast_ref::<&'static str>() {
259 return PanicMessage::StaticStr(s);
261 if let Ok(s) = payload.downcast::<String>() {
262 return PanicMessage::String(*s);
264 PanicMessage::Unknown
268 impl Into<Box<dyn Any + Send>> for PanicMessage {
269 fn into(self) -> Box<dyn Any + Send> {
271 PanicMessage::StaticStr(s) => Box::new(s),
272 PanicMessage::String(s) => Box::new(s),
273 PanicMessage::Unknown => {
274 struct UnknownPanicMessage;
275 Box::new(UnknownPanicMessage)
282 pub fn as_str(&self) -> Option<&str> {
284 PanicMessage::StaticStr(s) => Some(s),
285 PanicMessage::String(s) => Some(s),
286 PanicMessage::Unknown => None,
291 impl<S> Encode<S> for PanicMessage {
292 fn encode(self, w: &mut Writer, s: &mut S) {
293 self.as_str().encode(w, s);
297 impl<S> DecodeMut<'_, '_, S> for PanicMessage {
298 fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
299 match Option::<String>::decode(r, s) {
300 Some(s) => PanicMessage::String(s),
301 None => PanicMessage::Unknown,