| //! Serialization for client-server communication. | |
| use std::num::NonZero; | |
| use super::buffer::Buffer; | |
| pub(super) trait Encode<S>: Sized { | |
| fn encode(self, w: &mut Buffer, s: &mut S); | |
| } | |
| pub(super) trait Decode<'a, 's, S>: Sized { | |
| fn decode(r: &mut &'a [u8], s: &'s mut S) -> Self; | |
| } | |
| macro_rules! rpc_encode_decode { | |
| (le $ty:ty) => { | |
| impl<S> Encode<S> for $ty { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, _: &mut S) { | |
| w.extend_from_array(&self.to_le_bytes()); | |
| } | |
| } | |
| impl<S> Decode<'_, '_, S> for $ty { | |
| #[inline] | |
| fn decode(r: &mut &[u8], _: &mut S) -> Self { | |
| const N: usize = size_of::<$ty>(); | |
| let mut bytes = [0; N]; | |
| bytes.copy_from_slice(&r[..N]); | |
| *r = &r[N..]; | |
| Self::from_le_bytes(bytes) | |
| } | |
| } | |
| }; | |
| (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => { | |
| impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? { | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| $(self.$field.encode(w, s);)* | |
| } | |
| } | |
| impl<'a, S, $($($T: for<'s> Decode<'a, 's, S>),+)?> Decode<'a, '_, S> | |
| for $name $(<$($T),+>)? | |
| { | |
| #[inline] | |
| fn decode(r: &mut &'a [u8], s: &mut S) -> Self { | |
| $name { | |
| $($field: Decode::decode(r, s)),* | |
| } | |
| } | |
| } | |
| }; | |
| (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => { | |
| #[allow(non_upper_case_globals, non_camel_case_types)] | |
| const _: () = { | |
| #[repr(u8)] enum Tag { $($variant),* } | |
| $(const $variant: u8 = Tag::$variant as u8;)* | |
| impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| match self { | |
| $($name::$variant $(($field))* => { | |
| $variant.encode(w, s); | |
| $($field.encode(w, s);)* | |
| })* | |
| } | |
| } | |
| } | |
| impl<'a, S, $($($T: for<'s> Decode<'a, 's, S>),+)?> Decode<'a, '_, S> | |
| for $name $(<$($T),+>)? | |
| { | |
| #[inline] | |
| fn decode(r: &mut &'a [u8], s: &mut S) -> Self { | |
| match u8::decode(r, s) { | |
| $($variant => { | |
| $(let $field = Decode::decode(r, s);)* | |
| $name::$variant $(($field))* | |
| })* | |
| _ => unreachable!(), | |
| } | |
| } | |
| } | |
| }; | |
| } | |
| } | |
| impl<S> Encode<S> for () { | |
| #[inline] | |
| fn encode(self, _: &mut Buffer, _: &mut S) {} | |
| } | |
| impl<S> Decode<'_, '_, S> for () { | |
| #[inline] | |
| fn decode(_: &mut &[u8], _: &mut S) -> Self {} | |
| } | |
| impl<S> Encode<S> for u8 { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, _: &mut S) { | |
| w.push(self); | |
| } | |
| } | |
| impl<S> Decode<'_, '_, S> for u8 { | |
| #[inline] | |
| fn decode(r: &mut &[u8], _: &mut S) -> Self { | |
| let x = r[0]; | |
| *r = &r[1..]; | |
| x | |
| } | |
| } | |
| rpc_encode_decode!(le u32); | |
| #[cfg(target_pointer_width = "64")] | |
| rpc_encode_decode!(le usize); | |
| #[cfg(not(target_pointer_width = "64"))] | |
| const MAX_USIZE_SIZE: usize = 8; | |
| #[cfg(not(target_pointer_width = "64"))] | |
| impl<S> Encode<S> for usize { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, _: &mut S) { | |
| const N: usize = size_of::<usize>(); | |
| // We can pad with zeros without changing the value because of | |
| // little endian encoding. | |
| let mut bytes = [0; MAX_USIZE_SIZE]; | |
| bytes[..N].copy_from_slice(&self.to_le_bytes()); | |
| w.extend_from_array(&bytes); | |
| } | |
| } | |
| #[cfg(not(target_pointer_width = "64"))] | |
| impl<S> Decode<'_, '_, S> for usize { | |
| #[inline] | |
| fn decode(r: &mut &[u8], _: &mut S) -> Self { | |
| const N: usize = size_of::<usize>(); | |
| const { | |
| assert!(N <= MAX_USIZE_SIZE); | |
| } | |
| let mut bytes = [0; N]; | |
| bytes.copy_from_slice(&r[..N]); | |
| *r = &r[MAX_USIZE_SIZE..]; | |
| Self::from_le_bytes(bytes) | |
| } | |
| } | |
| impl<S> Encode<S> for bool { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| (self as u8).encode(w, s); | |
| } | |
| } | |
| impl<S> Decode<'_, '_, S> for bool { | |
| #[inline] | |
| fn decode(r: &mut &[u8], s: &mut S) -> Self { | |
| match u8::decode(r, s) { | |
| 0 => false, | |
| 1 => true, | |
| _ => unreachable!(), | |
| } | |
| } | |
| } | |
| impl<S> Encode<S> for NonZero<u32> { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| self.get().encode(w, s); | |
| } | |
| } | |
| impl<S> Decode<'_, '_, S> for NonZero<u32> { | |
| #[inline] | |
| fn decode(r: &mut &[u8], s: &mut S) -> Self { | |
| Self::new(u32::decode(r, s)).unwrap() | |
| } | |
| } | |
| impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| self.0.encode(w, s); | |
| self.1.encode(w, s); | |
| } | |
| } | |
| impl<'a, S, A: for<'s> Decode<'a, 's, S>, B: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> | |
| for (A, B) | |
| { | |
| #[inline] | |
| fn decode(r: &mut &'a [u8], s: &mut S) -> Self { | |
| (Decode::decode(r, s), Decode::decode(r, s)) | |
| } | |
| } | |
| impl<S> Encode<S> for &str { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| let bytes = self.as_bytes(); | |
| bytes.len().encode(w, s); | |
| w.extend_from_slice(bytes); | |
| } | |
| } | |
| impl<'a, S> Decode<'a, '_, S> for &'a str { | |
| #[inline] | |
| fn decode(r: &mut &'a [u8], s: &mut S) -> Self { | |
| let len = usize::decode(r, s); | |
| let xs = &r[..len]; | |
| *r = &r[len..]; | |
| str::from_utf8(xs).unwrap() | |
| } | |
| } | |
| impl<S> Encode<S> for String { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| self[..].encode(w, s); | |
| } | |
| } | |
| impl<S> Decode<'_, '_, S> for String { | |
| #[inline] | |
| fn decode(r: &mut &[u8], s: &mut S) -> Self { | |
| <&str>::decode(r, s).to_string() | |
| } | |
| } | |
| impl<S, T: Encode<S>> Encode<S> for Vec<T> { | |
| #[inline] | |
| fn encode(self, w: &mut Buffer, s: &mut S) { | |
| self.len().encode(w, s); | |
| for x in self { | |
| x.encode(w, s); | |
| } | |
| } | |
| } | |
| impl<'a, S, T: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> for Vec<T> { | |
| #[inline] | |
| fn decode(r: &mut &'a [u8], s: &mut S) -> Self { | |
| let len = usize::decode(r, s); | |
| let mut vec = Vec::with_capacity(len); | |
| for _ in 0..len { | |
| vec.push(T::decode(r, s)); | |
| } | |
| vec | |
| } | |
| } |