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);