@@ -159,7 +159,7 @@ void* __swift_bridge__$Vec_MyRustType$as_ptr(void* vec_ptr);
159
159
}
160
160
161
161
#[ test]
162
- fn extern_rust_fn_return_vec_of_opaque_rust_type ( ) {
162
+ fn extern_rust_type_vec_support ( ) {
163
163
CodegenTest {
164
164
bridge_module : bridge_module_tokens ( ) . into ( ) ,
165
165
expected_rust_tokens : expected_rust_tokens ( ) ,
@@ -268,7 +268,265 @@ void __swift_bridge__$some_function(void* arg);
268
268
}
269
269
270
270
#[ test]
271
- fn extern_rust_fn_return_vec_of_opaque_rust_type ( ) {
271
+ fn extern_rust_fn_arg_vec_of_opaque_rust_type ( ) {
272
+ CodegenTest {
273
+ bridge_module : bridge_module_tokens ( ) . into ( ) ,
274
+ expected_rust_tokens : expected_rust_tokens ( ) ,
275
+ expected_swift_code : expected_swift_code ( ) ,
276
+ expected_c_header : expected_c_header ( ) ,
277
+ }
278
+ . test ( ) ;
279
+ }
280
+ }
281
+
282
+ /// Verify that we emit Rust, Swift and C header code that allows a transparent enum be used
283
+ /// within a Vec<T>.
284
+ mod transparent_enum_vec_support {
285
+ use super :: * ;
286
+
287
+ fn bridge_module_tokens ( ) -> TokenStream {
288
+ quote ! {
289
+ mod ffi {
290
+ enum SomeEnum {
291
+ VariantA ,
292
+ VariantB
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ fn expected_rust_tokens ( ) -> ExpectedRustTokens {
299
+ ExpectedRustTokens :: Contains ( quote ! {
300
+ const _: ( ) = {
301
+ #[ doc( hidden) ]
302
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$new" ]
303
+ pub extern "C" fn _new( ) -> * mut Vec <SomeEnum > {
304
+ Box :: into_raw( Box :: new( Vec :: new( ) ) )
305
+ }
306
+
307
+ #[ doc( hidden) ]
308
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$drop" ]
309
+ pub extern "C" fn _drop( vec: * mut Vec <SomeEnum >) {
310
+ let vec = unsafe { Box :: from_raw( vec) } ;
311
+ drop( vec)
312
+ }
313
+
314
+ #[ doc( hidden) ]
315
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$len" ]
316
+ pub extern "C" fn _len( vec: * const Vec <SomeEnum >) -> usize {
317
+ unsafe { & * vec } . len( )
318
+ }
319
+
320
+ #[ doc( hidden) ]
321
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$get" ]
322
+ pub extern "C" fn _get( vec: * const Vec <SomeEnum >, index: usize ) -> __swift_bridge__Option_SomeEnum {
323
+ let vec = unsafe { & * vec } ;
324
+ let val = vec. get( index) . map( |v| * v) ;
325
+ __swift_bridge__Option_SomeEnum:: from_rust_repr( val)
326
+ }
327
+
328
+ #[ doc( hidden) ]
329
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$get_mut" ]
330
+ pub extern "C" fn _get_mut( vec: * mut Vec <SomeEnum >, index: usize ) -> __swift_bridge__Option_SomeEnum {
331
+ let vec = unsafe { & mut * vec } ;
332
+ let val = vec. get_mut( index) . map( |v| * v) ;
333
+ __swift_bridge__Option_SomeEnum:: from_rust_repr( val)
334
+ }
335
+
336
+ #[ doc( hidden) ]
337
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$push" ]
338
+ pub extern "C" fn _push( vec: * mut Vec <SomeEnum >, val: __swift_bridge__SomeEnum) {
339
+ unsafe { & mut * vec } . push( val. into_rust_repr( ) )
340
+ }
341
+
342
+ #[ doc( hidden) ]
343
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$pop" ]
344
+ pub extern "C" fn _pop( vec: * mut Vec <SomeEnum >) -> __swift_bridge__Option_SomeEnum {
345
+ let vec = unsafe { & mut * vec } ;
346
+ let val = vec. pop( ) ;
347
+ __swift_bridge__Option_SomeEnum:: from_rust_repr( val)
348
+ }
349
+
350
+ #[ doc( hidden) ]
351
+ #[ export_name = "__swift_bridge__$Vec_SomeEnum$as_ptr" ]
352
+ pub extern "C" fn _as_ptr( vec: * const Vec <SomeEnum >) -> * const SomeEnum {
353
+ unsafe { & * vec } . as_ptr( )
354
+ }
355
+ } ;
356
+ } )
357
+ }
358
+
359
+ fn expected_swift_code ( ) -> ExpectedSwiftCode {
360
+ ExpectedSwiftCode :: ContainsAfterTrim (
361
+ r#"
362
+ extension SomeEnum: Vectorizable {
363
+ public static func vecOfSelfNew() -> UnsafeMutableRawPointer {
364
+ __swift_bridge__$Vec_SomeEnum$new()
365
+ }
366
+
367
+ public static func vecOfSelfFree(vecPtr: UnsafeMutableRawPointer) {
368
+ __swift_bridge__$Vec_SomeEnum$drop(vecPtr)
369
+ }
370
+
371
+ public static func vecOfSelfPush(vecPtr: UnsafeMutableRawPointer, value: Self) {
372
+ __swift_bridge__$Vec_SomeEnum$push(vecPtr, value.intoFfiRepr())
373
+ }
374
+
375
+ public static func vecOfSelfPop(vecPtr: UnsafeMutableRawPointer) -> Optional<Self> {
376
+ let maybeEnum = __swift_bridge__$Vec_SomeEnum$pop(vecPtr)
377
+ return maybeEnum.intoSwiftRepr()
378
+ }
379
+
380
+ public static func vecOfSelfGet(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional<Self> {
381
+ let maybeEnum = __swift_bridge__$Vec_SomeEnum$get(vecPtr, index)
382
+ return maybeEnum.intoSwiftRepr()
383
+ }
384
+
385
+ public static func vecOfSelfGetMut(vecPtr: UnsafeMutableRawPointer, index: UInt) -> Optional<Self> {
386
+ let maybeEnum = __swift_bridge__$Vec_SomeEnum$get_mut(vecPtr, index)
387
+ return maybeEnum.intoSwiftRepr()
388
+ }
389
+
390
+ public static func vecOfSelfLen(vecPtr: UnsafeMutableRawPointer) -> UInt {
391
+ __swift_bridge__$Vec_SomeEnum$len(vecPtr)
392
+ }
393
+ }
394
+ "# ,
395
+ )
396
+ }
397
+
398
+ fn expected_c_header ( ) -> ExpectedCHeader {
399
+ ExpectedCHeader :: ContainsAfterTrim (
400
+ r#"
401
+ void* __swift_bridge__$Vec_SomeEnum$new(void);
402
+ void __swift_bridge__$Vec_SomeEnum$drop(void* vec_ptr);
403
+ void __swift_bridge__$Vec_SomeEnum$push(void* vec_ptr, __swift_bridge__$SomeEnum item);
404
+ __swift_bridge__$Option$SomeEnum __swift_bridge__$Vec_SomeEnum$pop(void* vec_ptr);
405
+ __swift_bridge__$Option$SomeEnum __swift_bridge__$Vec_SomeEnum$get(void* vec_ptr, uintptr_t index);
406
+ __swift_bridge__$Option$SomeEnum __swift_bridge__$Vec_SomeEnum$get_mut(void* vec_ptr, uintptr_t index);
407
+ uintptr_t __swift_bridge__$Vec_SomeEnum$len(void* vec_ptr);
408
+ void* __swift_bridge__$Vec_SomeEnum$as_ptr(void* vec_ptr);
409
+ "# ,
410
+ )
411
+ }
412
+
413
+ #[ test]
414
+ fn transparent_enum_vec_support ( ) {
415
+ CodegenTest {
416
+ bridge_module : bridge_module_tokens ( ) . into ( ) ,
417
+ expected_rust_tokens : expected_rust_tokens ( ) ,
418
+ expected_swift_code : expected_swift_code ( ) ,
419
+ expected_c_header : expected_c_header ( ) ,
420
+ }
421
+ . test ( ) ;
422
+ }
423
+ }
424
+
425
+ /// Test code generation for Rust function that returns a Vec<T> where T is a transparent enum.
426
+ mod extern_rust_fn_return_vec_of_transparent_enum {
427
+ use super :: * ;
428
+
429
+ fn bridge_module_tokens ( ) -> TokenStream {
430
+ quote ! {
431
+ mod ffi {
432
+ enum SomeEnum {
433
+ A
434
+ }
435
+
436
+ extern "Rust" {
437
+ fn some_function( ) -> Vec <SomeEnum >;
438
+ }
439
+ }
440
+ }
441
+ }
442
+
443
+ fn expected_rust_tokens ( ) -> ExpectedRustTokens {
444
+ ExpectedRustTokens :: Contains ( quote ! {
445
+ pub extern "C" fn __swift_bridge__some_function( ) -> * mut Vec <SomeEnum > {
446
+ Box :: into_raw( Box :: new( super :: some_function( ) ) )
447
+ }
448
+ } )
449
+ }
450
+
451
+ fn expected_swift_code ( ) -> ExpectedSwiftCode {
452
+ ExpectedSwiftCode :: ContainsAfterTrim (
453
+ r#"
454
+ func some_function() -> RustVec<SomeEnum> {
455
+ RustVec(ptr: __swift_bridge__$some_function())
456
+ }
457
+ "# ,
458
+ )
459
+ }
460
+
461
+ fn expected_c_header ( ) -> ExpectedCHeader {
462
+ ExpectedCHeader :: ContainsAfterTrim (
463
+ r#"
464
+ void* __swift_bridge__$some_function(void);
465
+ "# ,
466
+ )
467
+ }
468
+
469
+ #[ test]
470
+ fn extern_rust_fn_return_vec_of_transparent_enum ( ) {
471
+ CodegenTest {
472
+ bridge_module : bridge_module_tokens ( ) . into ( ) ,
473
+ expected_rust_tokens : expected_rust_tokens ( ) ,
474
+ expected_swift_code : expected_swift_code ( ) ,
475
+ expected_c_header : expected_c_header ( ) ,
476
+ }
477
+ . test ( ) ;
478
+ }
479
+ }
480
+
481
+ /// Test code generation for Rust function that has an argument
482
+ /// Vec<T> where T is a transparent enum.
483
+ mod extern_rust_fn_arg_vec_of_transparent_enum {
484
+ use super :: * ;
485
+
486
+ fn bridge_module_tokens ( ) -> TokenStream {
487
+ quote ! {
488
+ mod ffi {
489
+ enum SomeEnum {
490
+ A
491
+ }
492
+ extern "Rust" {
493
+ type MyRustType ;
494
+ fn some_function( arg: Vec <SomeEnum >) ;
495
+ }
496
+ }
497
+ }
498
+ }
499
+
500
+ fn expected_rust_tokens ( ) -> ExpectedRustTokens {
501
+ ExpectedRustTokens :: Contains ( quote ! {
502
+ pub extern "C" fn __swift_bridge__some_function(
503
+ arg: * mut Vec <SomeEnum >
504
+ ) {
505
+ super :: some_function( unsafe { * Box :: from_raw( arg) } )
506
+ }
507
+ } )
508
+ }
509
+
510
+ fn expected_swift_code ( ) -> ExpectedSwiftCode {
511
+ ExpectedSwiftCode :: ContainsAfterTrim (
512
+ r#"
513
+ func some_function(_ arg: RustVec<SomeEnum>) {
514
+ __swift_bridge__$some_function({ let val = arg; val.isOwned = false; return val.ptr }())
515
+ }
516
+ "# ,
517
+ )
518
+ }
519
+
520
+ fn expected_c_header ( ) -> ExpectedCHeader {
521
+ ExpectedCHeader :: ContainsAfterTrim (
522
+ r#"
523
+ void __swift_bridge__$some_function(void* arg);
524
+ "# ,
525
+ )
526
+ }
527
+
528
+ #[ test]
529
+ fn extern_rust_fn_arg_vec_of_transparent_enum ( ) {
272
530
CodegenTest {
273
531
bridge_module : bridge_module_tokens ( ) . into ( ) ,
274
532
expected_rust_tokens : expected_rust_tokens ( ) ,
0 commit comments