Skip to main content

wry_bindgen_runtime/wire/
encode.rs

1use alloc::boxed::Box;
2use alloc::string::{String, ToString};
3use alloc::vec::Vec;
4
5use super::{DecodeError, DecodedData, EncodedData, JsRef};
6
7pub trait BinaryEncode {
8    fn encode(self, encoder: &mut EncodedData);
9}
10
11pub trait BinaryDecode: Sized {
12    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError>;
13}
14
15pub trait JsRefEncode {
16    fn js_ref(&self) -> JsRef;
17}
18
19pub(crate) const TYPE_CACHED: u8 = 0xFF;
20pub(crate) const TYPE_FULL: u8 = 0xFE;
21
22#[repr(u8)]
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24enum TypeTag {
25    Null = 0,
26    Bool = 1,
27    U8 = 2,
28    U16 = 3,
29    U32 = 4,
30    U64 = 5,
31    U128 = 6,
32    I8 = 7,
33    I16 = 8,
34    I32 = 9,
35    I64 = 10,
36    I128 = 11,
37    F32 = 12,
38    F64 = 13,
39    Usize = 14,
40    Isize = 15,
41    String = 16,
42    HeapRef = 17,
43    Callback = 18,
44    Option = 19,
45    Result = 20,
46    Array = 21,
47    BorrowedRef = 22,
48    U8Clamped = 23,
49    StringEnum = 24,
50}
51
52#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
53pub struct TypeDef {
54    bytes: Vec<u8>,
55}
56
57#[derive(Clone, Copy)]
58pub struct FunctionTypeInfo<'a> {
59    type_id: u32,
60    can_use_cached: bool,
61    type_def: &'a TypeDef,
62}
63
64impl<'a> FunctionTypeInfo<'a> {
65    pub const fn new(type_id: u32, can_use_cached: bool, type_def: &'a TypeDef) -> Self {
66        Self {
67            type_id,
68            can_use_cached,
69            type_def,
70        }
71    }
72}
73
74impl BinaryEncode for FunctionTypeInfo<'_> {
75    fn encode(self, encoder: &mut EncodedData) {
76        if self.can_use_cached {
77            encoder.push_u8(TYPE_CACHED);
78            encoder.push_u32(self.type_id);
79        } else {
80            encoder.push_u8(TYPE_FULL);
81            encoder.push_u32(self.type_id);
82            for &byte in self.type_def.bytes() {
83                encoder.push_u8(byte);
84            }
85        }
86    }
87}
88
89impl TypeDef {
90    pub fn of<T: EncodeTypeDef + ?Sized>() -> Self {
91        let mut type_def = TypeDef::default();
92        T::encode_type_def(&mut type_def);
93        type_def
94    }
95
96    pub(crate) fn bytes(&self) -> &[u8] {
97        &self.bytes
98    }
99
100    pub(crate) fn heap_ref(&mut self) {
101        self.push_tag(TypeTag::HeapRef);
102    }
103
104    #[doc(hidden)]
105    pub fn borrowed_ref(&mut self) {
106        self.push_tag(TypeTag::BorrowedRef);
107    }
108
109    #[doc(hidden)]
110    pub fn u8_clamped(&mut self) {
111        self.push_tag(TypeTag::U8Clamped);
112    }
113
114    pub fn string_enum(&mut self, variants: &[&str]) {
115        self.push_tag(TypeTag::StringEnum);
116        self.push_u8(u8::try_from(variants.len()).expect("too many string enum variants"));
117        for variant in variants {
118            self.push_str(variant);
119        }
120    }
121
122    #[doc(hidden)]
123    pub fn callback<Signature: EncodeTypeDef + ?Sized>(&mut self) {
124        self.push_tag(TypeTag::Callback);
125        Signature::encode_type_def(self);
126    }
127
128    #[doc(hidden)]
129    pub fn callback_with_signature(
130        &mut self,
131        arg_count: u8,
132        encode_args_and_return: impl FnOnce(&mut TypeDef),
133    ) {
134        self.push_tag(TypeTag::Callback);
135        self.push_u8(arg_count);
136        encode_args_and_return(self);
137    }
138
139    fn push_tag(&mut self, tag: TypeTag) {
140        self.push_u8(tag as u8);
141    }
142
143    fn push_u8(&mut self, value: u8) {
144        self.bytes.push(value);
145    }
146
147    fn push_str(&mut self, value: &str) {
148        self.bytes
149            .extend_from_slice(&(value.len() as u32).to_le_bytes());
150        self.bytes.extend_from_slice(value.as_bytes());
151    }
152}
153
154pub trait EncodeTypeDef {
155    fn encode_type_def(type_def: &mut TypeDef);
156}
157
158impl EncodeTypeDef for () {
159    fn encode_type_def(type_def: &mut TypeDef) {
160        type_def.push_tag(TypeTag::Null);
161    }
162}
163
164impl BinaryEncode for () {
165    fn encode(self, _encoder: &mut EncodedData) {}
166}
167
168impl BinaryDecode for () {
169    fn decode(_decoder: &mut DecodedData) -> Result<Self, DecodeError> {
170        Ok(())
171    }
172}
173
174macro_rules! impl_num {
175    ($ty:ty, $tag:ident, $push:ident, $take:ident) => {
176        impl EncodeTypeDef for $ty {
177            fn encode_type_def(type_def: &mut TypeDef) {
178                type_def.push_tag(TypeTag::$tag);
179            }
180        }
181
182        impl BinaryEncode for $ty {
183            fn encode(self, encoder: &mut EncodedData) {
184                encoder.$push(self as _);
185            }
186        }
187
188        impl BinaryDecode for $ty {
189            fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
190                Ok(decoder.$take()? as $ty)
191            }
192        }
193    };
194}
195
196impl EncodeTypeDef for bool {
197    fn encode_type_def(type_def: &mut TypeDef) {
198        type_def.push_tag(TypeTag::Bool);
199    }
200}
201
202impl BinaryEncode for bool {
203    fn encode(self, encoder: &mut EncodedData) {
204        encoder.push_u8(if self { 1 } else { 0 });
205    }
206}
207
208impl BinaryDecode for bool {
209    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
210        Ok(decoder.take_u8()? != 0)
211    }
212}
213
214impl EncodeTypeDef for char {
215    fn encode_type_def(type_def: &mut TypeDef) {
216        type_def.push_tag(TypeTag::U32);
217    }
218}
219
220impl BinaryEncode for char {
221    fn encode(self, encoder: &mut EncodedData) {
222        encoder.push_u32(self as u32);
223    }
224}
225
226impl BinaryDecode for char {
227    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
228        char::from_u32(decoder.take_u32()?)
229            .ok_or_else(|| DecodeError::custom("invalid char scalar value"))
230    }
231}
232
233impl_num!(u8, U8, push_u8, take_u8);
234impl_num!(u16, U16, push_u16, take_u16);
235impl_num!(u32, U32, push_u32, take_u32);
236impl_num!(u64, U64, push_u64, take_u64);
237impl_num!(u128, U128, push_u128, take_u128);
238impl_num!(i8, I8, push_u8, take_u8);
239impl_num!(i16, I16, push_u16, take_u16);
240impl_num!(i32, I32, push_u32, take_u32);
241impl_num!(i64, I64, push_u64, take_u64);
242impl_num!(i128, I128, push_u128, take_u128);
243
244impl EncodeTypeDef for f32 {
245    fn encode_type_def(type_def: &mut TypeDef) {
246        type_def.push_tag(TypeTag::F32);
247    }
248}
249
250impl BinaryEncode for f32 {
251    fn encode(self, encoder: &mut EncodedData) {
252        encoder.push_u32(self.to_bits());
253    }
254}
255
256impl BinaryDecode for f32 {
257    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
258        Ok(f32::from_bits(decoder.take_u32()?))
259    }
260}
261
262impl EncodeTypeDef for f64 {
263    fn encode_type_def(type_def: &mut TypeDef) {
264        type_def.push_tag(TypeTag::F64);
265    }
266}
267
268impl BinaryEncode for f64 {
269    fn encode(self, encoder: &mut EncodedData) {
270        encoder.push_u64(self.to_bits());
271    }
272}
273
274impl BinaryDecode for f64 {
275    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
276        Ok(f64::from_bits(decoder.take_u64()?))
277    }
278}
279
280impl EncodeTypeDef for usize {
281    fn encode_type_def(type_def: &mut TypeDef) {
282        type_def.push_tag(TypeTag::Usize);
283    }
284}
285
286impl BinaryEncode for usize {
287    fn encode(self, encoder: &mut EncodedData) {
288        encoder.push_u64(self as u64);
289    }
290}
291
292impl BinaryDecode for usize {
293    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
294        Ok(decoder.take_u64()? as usize)
295    }
296}
297
298impl EncodeTypeDef for isize {
299    fn encode_type_def(type_def: &mut TypeDef) {
300        type_def.push_tag(TypeTag::Isize);
301    }
302}
303
304impl BinaryEncode for isize {
305    fn encode(self, encoder: &mut EncodedData) {
306        encoder.push_u64(self as u64);
307    }
308}
309
310impl BinaryDecode for isize {
311    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
312        Ok(decoder.take_u64()? as isize)
313    }
314}
315
316impl EncodeTypeDef for str {
317    fn encode_type_def(type_def: &mut TypeDef) {
318        type_def.push_tag(TypeTag::String);
319    }
320}
321
322impl EncodeTypeDef for &str {
323    fn encode_type_def(type_def: &mut TypeDef) {
324        str::encode_type_def(type_def);
325    }
326}
327
328impl<T: JsRefEncode + ?Sized> EncodeTypeDef for &T {
329    fn encode_type_def(type_def: &mut TypeDef) {
330        type_def.heap_ref();
331    }
332}
333
334impl BinaryEncode for &str {
335    fn encode(self, encoder: &mut EncodedData) {
336        encoder.push_str(self);
337    }
338}
339
340impl<T: JsRefEncode + ?Sized> BinaryEncode for &T {
341    fn encode(self, encoder: &mut EncodedData) {
342        self.js_ref().raw().encode(encoder);
343    }
344}
345
346impl EncodeTypeDef for String {
347    fn encode_type_def(type_def: &mut TypeDef) {
348        str::encode_type_def(type_def);
349    }
350}
351
352impl BinaryEncode for String {
353    fn encode(self, encoder: &mut EncodedData) {
354        encoder.push_str(&self);
355    }
356}
357
358impl BinaryDecode for String {
359    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
360        Ok(decoder.take_str()?.to_string())
361    }
362}
363
364impl<T: EncodeTypeDef> EncodeTypeDef for Option<T> {
365    fn encode_type_def(type_def: &mut TypeDef) {
366        type_def.push_tag(TypeTag::Option);
367        T::encode_type_def(type_def);
368    }
369}
370
371impl<T: BinaryDecode> BinaryDecode for Option<T> {
372    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
373        if decoder.take_u8()? != 0 {
374            Ok(Some(T::decode(decoder)?))
375        } else {
376            Ok(None)
377        }
378    }
379}
380
381impl<T: BinaryEncode> BinaryEncode for Option<T> {
382    fn encode(self, encoder: &mut EncodedData) {
383        match self {
384            Some(value) => {
385                encoder.push_u8(1);
386                value.encode(encoder);
387            }
388            None => encoder.push_u8(0),
389        }
390    }
391}
392
393impl<T: EncodeTypeDef, E: EncodeTypeDef> EncodeTypeDef for Result<T, E> {
394    fn encode_type_def(type_def: &mut TypeDef) {
395        type_def.push_tag(TypeTag::Result);
396        T::encode_type_def(type_def);
397        E::encode_type_def(type_def);
398    }
399}
400
401impl<T: BinaryEncode, E: BinaryEncode> BinaryEncode for Result<T, E> {
402    fn encode(self, encoder: &mut EncodedData) {
403        match self {
404            Ok(value) => {
405                encoder.push_u8(1);
406                value.encode(encoder);
407            }
408            Err(error) => {
409                encoder.push_u8(0);
410                error.encode(encoder);
411            }
412        }
413    }
414}
415
416impl<T: BinaryDecode, E: BinaryDecode> BinaryDecode for Result<T, E> {
417    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
418        if decoder.take_u8()? != 0 {
419            Ok(Ok(T::decode(decoder)?))
420        } else {
421            Ok(Err(E::decode(decoder)?))
422        }
423    }
424}
425
426impl<T: EncodeTypeDef> EncodeTypeDef for Vec<T> {
427    fn encode_type_def(type_def: &mut TypeDef) {
428        type_def.push_tag(TypeTag::Array);
429        T::encode_type_def(type_def);
430    }
431}
432
433impl<T: EncodeTypeDef> EncodeTypeDef for &[T] {
434    fn encode_type_def(type_def: &mut TypeDef) {
435        type_def.push_tag(TypeTag::Array);
436        T::encode_type_def(type_def);
437    }
438}
439
440impl<T: EncodeTypeDef> EncodeTypeDef for &mut [T] {
441    fn encode_type_def(type_def: &mut TypeDef) {
442        type_def.push_tag(TypeTag::Array);
443        T::encode_type_def(type_def);
444    }
445}
446
447impl<T: EncodeTypeDef> EncodeTypeDef for Box<[T]> {
448    fn encode_type_def(type_def: &mut TypeDef) {
449        type_def.push_tag(TypeTag::Array);
450        T::encode_type_def(type_def);
451    }
452}
453
454impl<T: BinaryEncode> BinaryEncode for Box<[T]> {
455    fn encode(self, encoder: &mut EncodedData) {
456        encoder.push_u32(self.len() as u32);
457        for val in self.into_vec() {
458            val.encode(encoder);
459        }
460    }
461}
462
463impl<T: BinaryEncode> BinaryEncode for Vec<T> {
464    fn encode(self, encoder: &mut EncodedData) {
465        encoder.push_u32(self.len() as u32);
466        for val in self {
467            val.encode(encoder);
468        }
469    }
470}
471
472impl<T: BinaryDecode> BinaryDecode for Vec<T> {
473    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
474        let len = decoder.take_u32()? as usize;
475        let mut vec = Vec::with_capacity(len);
476        for _ in 0..len {
477            vec.push(T::decode(decoder)?);
478        }
479        Ok(vec)
480    }
481}
482
483macro_rules! ref_encode_via_clone {
484    ($($ty:ty),* $(,)?) => {
485        $(
486            impl EncodeTypeDef for &$ty {
487                fn encode_type_def(type_def: &mut TypeDef) {
488                    <$ty as EncodeTypeDef>::encode_type_def(type_def);
489                }
490            }
491
492            impl BinaryEncode for &$ty {
493                fn encode(self, encoder: &mut EncodedData) {
494                    self.clone().encode(encoder);
495                }
496            }
497        )*
498    };
499}
500
501ref_encode_via_clone!(
502    bool, char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64, usize, isize, String,
503);
504
505macro_rules! slice_encode_via_copy {
506    ($($ty:ty),* $(,)?) => {
507        $(
508            impl BinaryEncode for &[$ty] {
509                fn encode(self, encoder: &mut EncodedData) {
510                    encoder.push_u32(self.len() as u32);
511                    for val in self {
512                        (*val).encode(encoder);
513                    }
514                }
515            }
516
517            impl BinaryEncode for &mut [$ty] {
518                fn encode(self, encoder: &mut EncodedData) {
519                    encoder.push_u32(self.len() as u32);
520                    for val in self {
521                        (*val).encode(encoder);
522                    }
523                }
524            }
525        )*
526    };
527}
528
529slice_encode_via_copy!(
530    bool, char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64, usize, isize
531);
532
533impl<T: JsRefEncode> BinaryEncode for &[T] {
534    fn encode(self, encoder: &mut EncodedData) {
535        encoder.push_u32(self.len() as u32);
536        for val in self {
537            val.js_ref().raw().encode(encoder);
538        }
539    }
540}
541
542impl<T: JsRefEncode> BinaryEncode for &mut [T] {
543    fn encode(self, encoder: &mut EncodedData) {
544        encoder.push_u32(self.len() as u32);
545        for val in self {
546            val.js_ref().raw().encode(encoder);
547        }
548    }
549}
550
551macro_rules! impl_fn_type_def {
552    (0,) => {
553        impl<R: EncodeTypeDef> EncodeTypeDef for fn() -> R {
554            fn encode_type_def(type_def: &mut TypeDef) {
555                type_def.push_u8(0);
556                R::encode_type_def(type_def);
557            }
558        }
559    };
560    ($n:expr, $($T:ident),+) => {
561        impl<$($T: EncodeTypeDef,)+ R: EncodeTypeDef> EncodeTypeDef for fn($($T),+) -> R {
562            fn encode_type_def(type_def: &mut TypeDef) {
563                type_def.push_u8($n);
564                $($T::encode_type_def(type_def);)+
565                R::encode_type_def(type_def);
566            }
567        }
568    };
569}
570
571impl_fn_type_def!(0,);
572impl_fn_type_def!(1, T1);
573impl_fn_type_def!(2, T1, T2);
574impl_fn_type_def!(3, T1, T2, T3);
575impl_fn_type_def!(4, T1, T2, T3, T4);
576impl_fn_type_def!(5, T1, T2, T3, T4, T5);
577impl_fn_type_def!(6, T1, T2, T3, T4, T5, T6);
578impl_fn_type_def!(7, T1, T2, T3, T4, T5, T6, T7);
579impl_fn_type_def!(8, T1, T2, T3, T4, T5, T6, T7, T8);
580impl_fn_type_def!(9, T1, T2, T3, T4, T5, T6, T7, T8, T9);
581impl_fn_type_def!(10, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
582impl_fn_type_def!(11, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
583impl_fn_type_def!(12, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
584impl_fn_type_def!(13, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
585impl_fn_type_def!(
586    14, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
587);
588impl_fn_type_def!(
589    15, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
590);
591impl_fn_type_def!(
592    16, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16
593);
594impl_fn_type_def!(
595    17, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17
596);
597impl_fn_type_def!(
598    18, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18
599);
600impl_fn_type_def!(
601    19, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19
602);
603impl_fn_type_def!(
604    20, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20
605);
606impl_fn_type_def!(
607    21, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
608    T21
609);
610impl_fn_type_def!(
611    22, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
612    T21, T22
613);
614impl_fn_type_def!(
615    23, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
616    T21, T22, T23
617);
618impl_fn_type_def!(
619    24, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
620    T21, T22, T23, T24
621);
622impl_fn_type_def!(
623    25, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
624    T21, T22, T23, T24, T25
625);
626impl_fn_type_def!(
627    26, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
628    T21, T22, T23, T24, T25, T26
629);
630impl_fn_type_def!(
631    27, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
632    T21, T22, T23, T24, T25, T26, T27
633);
634impl_fn_type_def!(
635    28, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
636    T21, T22, T23, T24, T25, T26, T27, T28
637);
638impl_fn_type_def!(
639    29, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
640    T21, T22, T23, T24, T25, T26, T27, T28, T29
641);
642impl_fn_type_def!(
643    30, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
644    T21, T22, T23, T24, T25, T26, T27, T28, T29, T30
645);
646impl_fn_type_def!(
647    31, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
648    T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31
649);
650impl_fn_type_def!(
651    32, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20,
652    T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32
653);