@@ -2,6 +2,22 @@ use crate::descriptor::{Descriptor, Function};
2
2
use crate :: js:: Context ;
3
3
use failure:: { bail, Error } ;
4
4
5
+ pub struct JsArgument {
6
+ pub optional : bool ,
7
+ pub name : String ,
8
+ pub type_ : String ,
9
+ }
10
+
11
+ impl JsArgument {
12
+ fn required ( name : String , type_ : String ) -> Self {
13
+ Self { optional : false , name, type_ }
14
+ }
15
+
16
+ fn optional ( name : String , type_ : String ) -> Self {
17
+ Self { optional : true , name, type_ }
18
+ }
19
+ }
20
+
5
21
/// Helper struct for manufacturing a shim in JS used to translate JS types to
6
22
/// Rust, aka pass from JS back into Rust
7
23
pub struct Js2Rust < ' a , ' b : ' a > {
@@ -12,7 +28,7 @@ pub struct Js2Rust<'a, 'b: 'a> {
12
28
rust_arguments : Vec < String > ,
13
29
14
30
/// Arguments and their types to the JS shim.
15
- pub js_arguments : Vec < ( String , String ) > ,
31
+ pub js_arguments : Vec < JsArgument > ,
16
32
17
33
/// Conversions that happen before we invoke the wasm function, such as
18
34
/// converting a string to a ptr/length pair.
@@ -175,7 +191,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
175
191
176
192
if let Some ( kind) = arg. vector_kind ( ) {
177
193
self . js_arguments
178
- . push ( ( name. clone ( ) , kind. js_ty ( ) . to_string ( ) ) ) ;
194
+ . push ( JsArgument :: required ( name. clone ( ) , kind. js_ty ( ) . to_string ( ) ) ) ;
179
195
180
196
let func = self . cx . pass_to_wasm_function ( kind) ?;
181
197
let val = if optional {
@@ -223,7 +239,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
223
239
}
224
240
225
241
if arg. is_anyref ( ) {
226
- self . js_arguments . push ( ( name. clone ( ) , "any" . to_string ( ) ) ) ;
242
+ self . js_arguments . push ( JsArgument :: required ( name. clone ( ) , "any" . to_string ( ) ) ) ;
227
243
if self . cx . config . anyref {
228
244
if optional {
229
245
self . cx . expose_add_to_anyref_table ( ) ?;
@@ -252,7 +268,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
252
268
253
269
if arg. is_wasm_native ( ) {
254
270
self . js_arguments
255
- . push ( ( name. clone ( ) , "number | undefined " . to_string ( ) ) ) ;
271
+ . push ( JsArgument :: optional ( name. clone ( ) , "number" . to_string ( ) ) ) ;
256
272
257
273
if self . cx . config . debug {
258
274
self . cx . expose_assert_num ( ) ;
@@ -274,7 +290,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
274
290
275
291
if arg. is_abi_as_u32 ( ) {
276
292
self . js_arguments
277
- . push ( ( name. clone ( ) , "number | undefined " . to_string ( ) ) ) ;
293
+ . push ( JsArgument :: optional ( name. clone ( ) , "number" . to_string ( ) ) ) ;
278
294
279
295
if self . cx . config . debug {
280
296
self . cx . expose_assert_num ( ) ;
@@ -301,7 +317,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
301
317
} ;
302
318
self . cx . expose_uint32_memory ( ) ;
303
319
self . js_arguments
304
- . push ( ( name. clone ( ) , "BigInt | undefined " . to_string ( ) ) ) ;
320
+ . push ( JsArgument :: optional ( name. clone ( ) , "BigInt" . to_string ( ) ) ) ;
305
321
self . prelude ( & format ! (
306
322
"
307
323
{f}[0] = isLikeNone({name}) ? BigInt(0) : {name};
@@ -322,7 +338,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
322
338
match * arg {
323
339
Descriptor :: Boolean => {
324
340
self . js_arguments
325
- . push ( ( name. clone ( ) , "boolean | undefined " . to_string ( ) ) ) ;
341
+ . push ( JsArgument :: optional ( name. clone ( ) , "boolean" . to_string ( ) ) ) ;
326
342
if self . cx . config . debug {
327
343
self . cx . expose_assert_bool ( ) ;
328
344
self . prelude ( & format ! (
@@ -339,21 +355,21 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
339
355
}
340
356
Descriptor :: Char => {
341
357
self . js_arguments
342
- . push ( ( name. clone ( ) , "string | undefined " . to_string ( ) ) ) ;
358
+ . push ( JsArgument :: optional ( name. clone ( ) , "string" . to_string ( ) ) ) ;
343
359
self . rust_arguments . push ( format ! (
344
360
"isLikeNone({0}) ? 0xFFFFFF : {0}.codePointAt(0)" ,
345
361
name
346
362
) ) ;
347
363
}
348
364
Descriptor :: Enum { hole } => {
349
365
self . js_arguments
350
- . push ( ( name. clone ( ) , "number | undefined " . to_string ( ) ) ) ;
366
+ . push ( JsArgument :: optional ( name. clone ( ) , "number" . to_string ( ) ) ) ;
351
367
self . rust_arguments
352
368
. push ( format ! ( "isLikeNone({0}) ? {1} : {0}" , name, hole) ) ;
353
369
}
354
370
Descriptor :: RustStruct ( ref s) => {
355
371
self . js_arguments
356
- . push ( ( name. clone ( ) , format ! ( "{} | undefined" , s ) ) ) ;
372
+ . push ( JsArgument :: optional ( name. clone ( ) , s . to_string ( ) ) ) ;
357
373
self . prelude ( & format ! ( "let ptr{} = 0;" , i) ) ;
358
374
self . prelude ( & format ! ( "if (!isLikeNone({0})) {{" , name) ) ;
359
375
self . assert_class ( & name, s) ;
@@ -373,7 +389,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
373
389
}
374
390
375
391
if let Some ( s) = arg. rust_struct ( ) {
376
- self . js_arguments . push ( ( name. clone ( ) , s. to_string ( ) ) ) ;
392
+ self . js_arguments . push ( JsArgument :: required ( name. clone ( ) , s. to_string ( ) ) ) ;
377
393
self . assert_class ( & name, s) ;
378
394
self . assert_not_moved ( & name) ;
379
395
if arg. is_by_ref ( ) {
@@ -387,7 +403,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
387
403
}
388
404
389
405
if arg. number ( ) . is_some ( ) {
390
- self . js_arguments . push ( ( name. clone ( ) , "number" . to_string ( ) ) ) ;
406
+ self . js_arguments . push ( JsArgument :: required ( name. clone ( ) , "number" . to_string ( ) ) ) ;
391
407
392
408
if self . cx . config . debug {
393
409
self . cx . expose_assert_num ( ) ;
@@ -405,7 +421,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
405
421
self . cx . expose_uint64_cvt_shim ( )
406
422
} ;
407
423
self . cx . expose_uint32_memory ( ) ;
408
- self . js_arguments . push ( ( name. clone ( ) , "BigInt" . to_string ( ) ) ) ;
424
+ self . js_arguments . push ( JsArgument :: required ( name. clone ( ) , "BigInt" . to_string ( ) ) ) ;
409
425
self . prelude ( & format ! (
410
426
"
411
427
{f}[0] = {name};
@@ -422,7 +438,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
422
438
}
423
439
424
440
if arg. is_ref_anyref ( ) {
425
- self . js_arguments . push ( ( name. clone ( ) , "any" . to_string ( ) ) ) ;
441
+ self . js_arguments . push ( JsArgument :: required ( name. clone ( ) , "any" . to_string ( ) ) ) ;
426
442
if self . cx . config . anyref {
427
443
self . anyref_args . push ( ( self . rust_arguments . len ( ) , false ) ) ;
428
444
self . rust_arguments . push ( name) ;
@@ -442,7 +458,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
442
458
match * arg {
443
459
Descriptor :: Boolean => {
444
460
self . js_arguments
445
- . push ( ( name. clone ( ) , "boolean" . to_string ( ) ) ) ;
461
+ . push ( JsArgument :: required ( name. clone ( ) , "boolean" . to_string ( ) ) ) ;
446
462
if self . cx . config . debug {
447
463
self . cx . expose_assert_bool ( ) ;
448
464
self . prelude ( & format ! (
@@ -455,7 +471,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
455
471
self . rust_arguments . push ( format ! ( "{}" , name) ) ;
456
472
}
457
473
Descriptor :: Char => {
458
- self . js_arguments . push ( ( name. clone ( ) , "string" . to_string ( ) ) ) ;
474
+ self . js_arguments . push ( JsArgument :: required ( name. clone ( ) , "string" . to_string ( ) ) ) ;
459
475
self . rust_arguments . push ( format ! ( "{}.codePointAt(0)" , name) )
460
476
}
461
477
_ => bail ! (
@@ -737,7 +753,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
737
753
let mut ret: String = self
738
754
. js_arguments
739
755
. iter ( )
740
- . map ( |a| format ! ( "@param {{{}}} {}\n " , a. 1 , a. 0 ) )
756
+ . map ( |a| if a. optional {
757
+ format ! ( "@param {{{} | undefined}} {}\n " , a. type_, a. name)
758
+ } else {
759
+ format ! ( "@param {{{}}} {}\n " , a. type_, a. name)
760
+ } )
741
761
. collect ( ) ;
742
762
ret. push_str ( & format ! ( "@returns {{{}}}" , self . ret_ty) ) ;
743
763
ret
@@ -761,7 +781,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
761
781
let js_args = self
762
782
. js_arguments
763
783
. iter ( )
764
- . map ( |s| & s. 0 [ ..] )
784
+ . map ( |s| & s. name [ ..] )
765
785
. collect :: < Vec < _ > > ( )
766
786
. join ( ", " ) ;
767
787
let mut js = format ! ( "{}({}) {{\n " , prefix, js_args) ;
@@ -790,7 +810,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
790
810
let ts_args = self
791
811
. js_arguments
792
812
. iter ( )
793
- . map ( |s| format ! ( "{}: {}" , s. 0 , s. 1 ) )
813
+ . map ( |s| if s. optional {
814
+ format ! ( "{}?: {}" , s. name, s. type_)
815
+ } else {
816
+ format ! ( "{}: {}" , s. name, s. type_)
817
+ } )
794
818
. collect :: < Vec < _ > > ( )
795
819
. join ( ", " ) ;
796
820
let mut ts = if prefix. is_empty ( ) {
0 commit comments