1 //! Serialization for client-server communication.
6 use std
::num
::NonZeroU32
;
10 pub(super) type Writer
= super::buffer
::Buffer
<u8>;
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 { $($field:ident),* $(,)? }
) => {
47 impl<S
> Encode
<S
> for $name
{
48 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
49 $
(self.$field
.encode(w
, s
);)*
53 impl<S
> DecodeMut
<'_
, '_
, S
> for $name
{
54 fn decode(r
: &mut Reader
<'_
>, s
: &mut S
) -> Self {
56 $
($field
: DecodeMut
::decode(r
, s
)),*
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)]
68 #[repr(u8)] enum Tag { $($variant),* }
70 $
(pub const $variant
: u8 = Tag
::$variant
as u8;)*
74 $
($name
::$variant $
(($field
))* => {
75 tag
::$variant
.encode(w
, s
);
76 $
($field
.encode(w
, s
);)*
82 impl<S
, $
($
($T
: for<'s
> DecodeMut
<'a
, 's
, S
>),+)?
> DecodeMut
<'a
, '_
, S
>
83 for $name $
(<$
($T
),+>)?
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)]
90 #[repr(u8)] enum Tag { $($variant),* }
92 $
(pub const $variant
: u8 = Tag
::$variant
as u8;)*
95 match u8::decode(r
, s
) {
97 $
(let $field
= DecodeMut
::decode(r
, s
);)*
98 $name
::$variant $
(($field
))*
107 impl<S
> Encode
<S
> for () {
108 fn encode(self, _
: &mut Writer
, _
: &mut S
) {}
111 impl<S
> DecodeMut
<'_
, '_
, S
> for () {
112 fn decode(_
: &mut Reader
<'_
>, _
: &mut S
) -> Self {}
115 impl<S
> Encode
<S
> for u8 {
116 fn encode(self, w
: &mut Writer
, _
: &mut S
) {
121 impl<S
> DecodeMut
<'_
, '_
, S
> for u8 {
122 fn decode(r
: &mut Reader
<'_
>, _
: &mut S
) -> Self {
129 rpc_encode_decode
!(le
u32);
130 rpc_encode_decode
!(le
usize);
132 impl<S
> Encode
<S
> for bool
{
133 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
134 (self as u8).encode(w
, s
);
138 impl<S
> DecodeMut
<'_
, '_
, S
> for bool
{
139 fn decode(r
: &mut Reader
<'_
>, s
: &mut S
) -> Self {
140 match u8::decode(r
, s
) {
148 impl<S
> Encode
<S
> for char {
149 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
150 (self as u32).encode(w
, s
);
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()
160 impl<S
> Encode
<S
> for NonZeroU32
{
161 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
162 self.get().encode(w
, s
);
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()
172 impl<S
, A
: Encode
<S
>, B
: Encode
<S
>> Encode
<S
> for (A
, B
) {
173 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
179 impl<S
, A
: for<'s
> DecodeMut
<'a
, 's
, S
>, B
: for<'s
> DecodeMut
<'a
, 's
, S
>> DecodeMut
<'a
, '_
, S
>
182 fn decode(r
: &mut Reader
<'a
>, s
: &mut S
) -> Self {
183 (DecodeMut
::decode(r
, s
), DecodeMut
::decode(r
, s
))
209 impl<S
> Encode
<S
> for &[u8] {
210 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
211 self.len().encode(w
, s
);
212 w
.write_all(self).unwrap();
216 impl<S
> DecodeMut
<'a
, '_
, S
> for &'a
[u8] {
217 fn decode(r
: &mut Reader
<'a
>, s
: &mut S
) -> Self {
218 let len
= usize::decode(r
, s
);
225 impl<S
> Encode
<S
> for &str {
226 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
227 self.as_bytes().encode(w
, s
);
231 impl<S
> DecodeMut
<'a
, '_
, S
> for &'a
str {
232 fn decode(r
: &mut Reader
<'a
>, s
: &mut S
) -> Self {
233 str::from_utf8(<&[u8]>::decode(r
, s
)).unwrap()
237 impl<S
> Encode
<S
> for String
{
238 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
239 self[..].encode(w
, s
);
243 impl<S
> DecodeMut
<'_
, '_
, S
> for String
{
244 fn decode(r
: &mut Reader
<'_
>, s
: &mut S
) -> Self {
245 <&str>::decode(r
, s
).to_string()
249 /// Simplied version of panic payloads, ignoring
250 /// types other than `&'static str` and `String`.
251 pub enum PanicMessage
{
252 StaticStr(&'
static str),
257 impl From
<Box
<dyn Any
+ Send
>> for PanicMessage
{
258 fn from(payload
: Box
<dyn Any
+ Send
+ '
static>) -> Self {
259 if let Some(s
) = payload
.downcast_ref
::<&'
static str>() {
260 return PanicMessage
::StaticStr(s
);
262 if let Ok(s
) = payload
.downcast
::<String
>() {
263 return PanicMessage
::String(*s
);
265 PanicMessage
::Unknown
269 impl Into
<Box
<dyn Any
+ Send
>> for PanicMessage
{
270 fn into(self) -> Box
<dyn Any
+ Send
> {
272 PanicMessage
::StaticStr(s
) => Box
::new(s
),
273 PanicMessage
::String(s
) => Box
::new(s
),
274 PanicMessage
::Unknown
=> {
275 struct UnknownPanicMessage
;
276 Box
::new(UnknownPanicMessage
)
283 pub fn as_str(&self) -> Option
<&str> {
285 PanicMessage
::StaticStr(s
) => Some(s
),
286 PanicMessage
::String(s
) => Some(s
),
287 PanicMessage
::Unknown
=> None
,
292 impl<S
> Encode
<S
> for PanicMessage
{
293 fn encode(self, w
: &mut Writer
, s
: &mut S
) {
294 self.as_str().encode(w
, s
);
298 impl<S
> DecodeMut
<'_
, '_
, S
> for PanicMessage
{
299 fn decode(r
: &mut Reader
<'_
>, s
: &mut S
) -> Self {
300 match Option
::<String
>::decode(r
, s
) {
301 Some(s
) => PanicMessage
::String(s
),
302 None
=> PanicMessage
::Unknown
,