1 #![allow(dead_code)] 2 #![expect(clippy::allow_attributes_without_reason, reason = "crate not migrated")] 3 4 macro_rules! gentest { 5 ($id:ident $name:tt $path:tt) => { 6 mod $id { 7 mod sugar { 8 wasmtime::component::bindgen!(in $path); 9 } 10 mod async_ { 11 wasmtime::component::bindgen!({ 12 path: $path, 13 async: true, 14 }); 15 } 16 mod tracing { 17 wasmtime::component::bindgen!({ 18 path: $path, 19 tracing: true, 20 verbose_tracing: true, 21 ownership: Borrowing { 22 duplicate_if_necessary: true 23 } 24 }); 25 } 26 } 27 }; 28 } 29 30 component_macro_test_helpers::foreach!(gentest); 31 32 mod with_key_and_resources { 33 use anyhow::Result; 34 use wasmtime::component::Resource; 35 36 wasmtime::component::bindgen!({ 37 inline: " 38 package demo:pkg; 39 40 interface bar { 41 resource a; 42 resource b; 43 } 44 45 world foo { 46 resource a; 47 resource b; 48 49 import foo: interface { 50 resource a; 51 resource b; 52 } 53 54 import bar; 55 } 56 ", 57 with: { 58 "a": MyA, 59 "b": MyA, 60 "foo/a": MyA, 61 "foo/b": MyA, 62 "demo:pkg/bar/a": MyA, 63 "demo:pkg/bar/b": MyA, 64 }, 65 }); 66 67 pub struct MyA; 68 69 struct MyComponent; 70 71 impl FooImports for MyComponent {} 72 73 impl HostA for MyComponent { 74 fn drop(&mut self, _: Resource<MyA>) -> Result<()> { 75 loop {} 76 } 77 } 78 79 impl HostB for MyComponent { 80 fn drop(&mut self, _: Resource<MyA>) -> Result<()> { 81 loop {} 82 } 83 } 84 85 impl foo::Host for MyComponent {} 86 87 impl foo::HostA for MyComponent { 88 fn drop(&mut self, _: Resource<MyA>) -> Result<()> { 89 loop {} 90 } 91 } 92 93 impl foo::HostB for MyComponent { 94 fn drop(&mut self, _: Resource<MyA>) -> Result<()> { 95 loop {} 96 } 97 } 98 99 impl demo::pkg::bar::Host for MyComponent {} 100 101 impl demo::pkg::bar::HostA for MyComponent { 102 fn drop(&mut self, _: Resource<MyA>) -> Result<()> { 103 loop {} 104 } 105 } 106 107 impl demo::pkg::bar::HostB for MyComponent { 108 fn drop(&mut self, _: Resource<MyA>) -> Result<()> { 109 loop {} 110 } 111 } 112 } 113 114 mod trappable_errors_with_versioned_and_unversioned_packages { 115 wasmtime::component::bindgen!({ 116 world: "foo:foo/nope", 117 inline: " 118 package foo:[email protected]; 119 120 interface a { 121 variant error { 122 other(string), 123 } 124 125 f: func() -> result<_, error>; 126 } 127 128 world foo { 129 import a; 130 } 131 ", 132 path: "tests/codegen/unversioned-foo.wit", 133 trappable_error_type: { 134 "foo:foo/[email protected]/error" => MyX, 135 }, 136 }); 137 138 #[allow(dead_code)] 139 type MyX = u64; 140 } 141 142 mod trappable_errors { 143 wasmtime::component::bindgen!({ 144 inline: " 145 package demo:pkg; 146 147 interface a { 148 type b = u64; 149 150 z1: func() -> result<_, b>; 151 z2: func() -> result<_, b>; 152 } 153 154 interface b { 155 use a.{b}; 156 z: func() -> result<_, b>; 157 } 158 159 interface c { 160 type b = u64; 161 } 162 163 interface d { 164 use c.{b}; 165 z: func() -> result<_, b>; 166 } 167 168 world foo { 169 import a; 170 import b; 171 import d; 172 } 173 ", 174 trappable_error_type: { 175 "demo:pkg/a/b" => MyX, 176 "demo:pkg/c/b" => MyX, 177 }, 178 }); 179 180 #[allow(dead_code)] 181 type MyX = u32; 182 } 183 184 mod interface_name_with_rust_keyword { 185 wasmtime::component::bindgen!({ 186 inline: " 187 package foo:foo; 188 189 interface crate { } 190 191 world foo { 192 export crate; 193 } 194 " 195 }); 196 } 197 198 mod with_works_with_hierarchy { 199 mod bindings { 200 wasmtime::component::bindgen!({ 201 inline: " 202 package foo:foo; 203 204 interface a { 205 record t { 206 x: u32, 207 } 208 x: func() -> t; 209 } 210 211 interface b { 212 use a.{t}; 213 x: func() -> t; 214 } 215 216 interface c { 217 use b.{t}; 218 x: func() -> t; 219 } 220 221 world foo { 222 import c; 223 } 224 " 225 }); 226 } 227 228 mod with_just_one_interface { 229 wasmtime::component::bindgen!({ 230 inline: " 231 package foo:foo; 232 233 interface a { 234 record t { 235 x: u32, 236 } 237 x: func() -> t; 238 } 239 240 interface b { 241 use a.{t}; 242 x: func() -> t; 243 } 244 245 interface c { 246 use b.{t}; 247 x: func() -> t; 248 } 249 250 world foo { 251 use c.{t}; 252 253 import x: func() -> t; 254 } 255 ", 256 with: { "foo:foo/a": super::bindings::foo::foo::a } 257 }); 258 259 struct X; 260 261 impl FooImports for X { 262 fn x(&mut self) -> super::bindings::foo::foo::a::T { 263 loop {} 264 } 265 } 266 } 267 268 mod with_whole_package { 269 wasmtime::component::bindgen!({ 270 inline: " 271 package foo:foo; 272 273 interface a { 274 record t { 275 x: u32, 276 } 277 x: func() -> t; 278 } 279 280 interface b { 281 use a.{t}; 282 x: func() -> t; 283 } 284 285 interface c { 286 use b.{t}; 287 x: func() -> t; 288 } 289 290 world foo { 291 use c.{t}; 292 293 import x: func() -> t; 294 } 295 ", 296 with: { "foo:foo": super::bindings::foo::foo } 297 }); 298 299 struct X; 300 301 impl FooImports for X { 302 fn x(&mut self) -> super::bindings::foo::foo::a::T { 303 loop {} 304 } 305 } 306 } 307 308 mod with_whole_namespace { 309 wasmtime::component::bindgen!({ 310 inline: " 311 package foo:foo; 312 313 interface a { 314 record t { 315 x: u32, 316 } 317 x: func() -> t; 318 } 319 320 interface b { 321 use a.{t}; 322 x: func() -> t; 323 } 324 325 interface c { 326 use b.{t}; 327 x: func() -> t; 328 } 329 330 world foo { 331 use c.{t}; 332 333 import x: func() -> t; 334 } 335 ", 336 with: { "foo": super::bindings::foo } 337 }); 338 339 struct X; 340 341 impl FooImports for X { 342 fn x(&mut self) -> super::bindings::foo::foo::a::T { 343 loop {} 344 } 345 } 346 } 347 } 348 349 mod trappable_imports { 350 mod none { 351 wasmtime::component::bindgen!({ 352 inline: " 353 package foo:foo; 354 355 world foo { 356 import foo: func(); 357 } 358 ", 359 trappable_imports: false, 360 }); 361 struct X; 362 363 impl FooImports for X { 364 fn foo(&mut self) {} 365 } 366 } 367 368 mod all { 369 wasmtime::component::bindgen!({ 370 inline: " 371 package foo:foo; 372 373 world foo { 374 import foo: func(); 375 } 376 ", 377 trappable_imports: true, 378 }); 379 struct X; 380 381 impl FooImports for X { 382 fn foo(&mut self) -> wasmtime::Result<()> { 383 Ok(()) 384 } 385 } 386 } 387 388 mod some { 389 wasmtime::component::bindgen!({ 390 inline: " 391 package foo:foo; 392 393 world foo { 394 import foo: func(); 395 import bar: func(); 396 } 397 ", 398 trappable_imports: ["foo"], 399 }); 400 struct X; 401 402 impl FooImports for X { 403 fn foo(&mut self) -> wasmtime::Result<()> { 404 Ok(()) 405 } 406 fn bar(&mut self) {} 407 } 408 } 409 410 mod across_interfaces { 411 use wasmtime::component::Resource; 412 413 wasmtime::component::bindgen!({ 414 inline: " 415 package foo:foo; 416 417 interface a { 418 foo: func(); 419 bar: func(); 420 421 resource r { 422 constructor(); 423 foo: func(); 424 bar: static func(); 425 } 426 } 427 428 world foo { 429 import a; 430 import foo: func(); 431 import bar: func(); 432 import i: interface { 433 foo: func(); 434 bar: func(); 435 } 436 437 } 438 ", 439 trappable_imports: ["foo"], 440 with: { "foo:foo/a/r": R }, 441 }); 442 443 struct X; 444 pub struct R; 445 446 impl FooImports for X { 447 fn foo(&mut self) -> wasmtime::Result<()> { 448 Ok(()) 449 } 450 fn bar(&mut self) {} 451 } 452 453 impl i::Host for X { 454 fn foo(&mut self) -> wasmtime::Result<()> { 455 Ok(()) 456 } 457 fn bar(&mut self) {} 458 } 459 460 impl foo::foo::a::Host for X { 461 fn foo(&mut self) -> wasmtime::Result<()> { 462 Ok(()) 463 } 464 fn bar(&mut self) {} 465 } 466 467 impl foo::foo::a::HostR for X { 468 fn new(&mut self) -> Resource<R> { 469 loop {} 470 } 471 fn foo(&mut self, _: Resource<R>) {} 472 fn bar(&mut self) {} 473 fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> { 474 Ok(()) 475 } 476 } 477 } 478 479 mod resources { 480 use wasmtime::component::Resource; 481 482 wasmtime::component::bindgen!({ 483 inline: " 484 package foo:foo; 485 486 interface a { 487 resource r { 488 constructor(); 489 foo: func(); 490 bar: static func(); 491 } 492 } 493 494 world foo { 495 import a; 496 497 } 498 ", 499 trappable_imports: [ 500 "[constructor]r", 501 "[method]r.foo", 502 "[static]r.bar", 503 ], 504 with: { "foo:foo/a/r": R }, 505 }); 506 507 struct X; 508 pub struct R; 509 510 impl foo::foo::a::Host for X {} 511 512 impl foo::foo::a::HostR for X { 513 fn new(&mut self) -> wasmtime::Result<Resource<R>> { 514 loop {} 515 } 516 fn foo(&mut self, _: Resource<R>) -> wasmtime::Result<()> { 517 Ok(()) 518 } 519 fn bar(&mut self) -> wasmtime::Result<()> { 520 Ok(()) 521 } 522 fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> { 523 Ok(()) 524 } 525 } 526 } 527 } 528 529 mod custom_derives { 530 use std::collections::{hash_map::RandomState, HashSet}; 531 532 wasmtime::component::bindgen!({ 533 inline: " 534 package my:inline; 535 536 interface blah { 537 variant abc { 538 a, 539 b, 540 c 541 } 542 543 record foo { 544 field1: string, 545 field2: list<u32>, 546 field3: abc 547 } 548 549 bar: func(cool: foo); 550 } 551 552 world baz { 553 import blah; 554 } 555 ", 556 // Clone is included by default almost everywhere, so include it here to make sure it 557 // doesn't conflict 558 additional_derives: [serde::Serialize, serde::Deserialize, Hash, Clone, PartialEq, Eq], 559 }); 560 561 use my::inline::blah::{Abc, Foo, Host}; 562 563 struct X; 564 565 impl Host for X { 566 fn bar(&mut self, cool: Foo) { 567 // Check that built in derives that I've added actually work by seeing that this hashes 568 let _blah: HashSet<Foo, RandomState> = HashSet::from_iter([Foo { 569 field1: "hello".to_string(), 570 field2: vec![1, 2, 3], 571 field3: Abc::B, 572 }]); 573 574 // Check that the attributes from an external crate actually work. If they don't work, 575 // compilation will fail here 576 let _ = serde_json::to_string(&cool); 577 } 578 } 579 } 580 581 mod with_and_mixing_async { 582 mod with_async { 583 wasmtime::component::bindgen!({ 584 inline: " 585 package my:inline; 586 interface foo { 587 type t = u32; 588 foo: func() -> t; 589 } 590 interface bar { 591 use foo.{t}; 592 bar: func() -> t; 593 } 594 world x { 595 import bar; 596 } 597 ", 598 async: { 599 only_imports: ["bar"], 600 }, 601 }); 602 } 603 604 mod without_async { 605 wasmtime::component::bindgen!({ 606 inline: " 607 package my:inline; 608 interface foo { 609 type t = u32; 610 foo: func() -> t; 611 } 612 interface bar { 613 use foo.{t}; 614 bar: func() -> t; 615 } 616 world x { 617 import bar; 618 } 619 ", 620 with: { 621 "my:inline/foo": super::with_async::my::inline::foo, 622 }, 623 require_store_data_send: true, 624 }); 625 } 626 627 mod third { 628 wasmtime::component::bindgen!({ 629 inline: " 630 package my:inline; 631 interface foo { 632 type t = u32; 633 foo: func() -> t; 634 } 635 interface bar { 636 use foo.{t}; 637 bar: func() -> t; 638 } 639 interface baz { 640 use bar.{t}; 641 baz: func() -> t; 642 } 643 world x { 644 import baz; 645 } 646 ", 647 with: { 648 "my:inline/foo": super::with_async::my::inline::foo, 649 "my:inline/bar": super::without_async::my::inline::bar, 650 }, 651 require_store_data_send: true, 652 }); 653 } 654 } 655 656 mod trappable_error_type_and_versions { 657 struct MyError; 658 659 mod package_no_version_path_no_version { 660 wasmtime::component::bindgen!({ 661 inline: " 662 package my:inline; 663 interface i { 664 enum e { a, b, c } 665 } 666 world foo {} 667 ", 668 trappable_error_type: { 669 "my:inline/i/e" => super::MyError, 670 }, 671 }); 672 } 673 mod package_version_path_no_version { 674 wasmtime::component::bindgen!({ 675 inline: " 676 package my:[email protected]; 677 interface i { 678 enum e { a, b, c } 679 } 680 world foo {} 681 ", 682 trappable_error_type: { 683 "my:inline/i/e" => super::MyError, 684 }, 685 }); 686 } 687 mod package_version_path_version { 688 wasmtime::component::bindgen!({ 689 inline: " 690 package my:[email protected]; 691 interface i { 692 enum e { a, b, c } 693 } 694 world foo {} 695 ", 696 trappable_error_type: { 697 "my:inline/[email protected]/e" => super::MyError, 698 }, 699 }); 700 } 701 } 702 703 mod paths { 704 mod multiple_paths { 705 wasmtime::component::bindgen!({ 706 world: "test:paths/test", 707 inline: r#" 708 package test:paths; 709 world test { 710 import paths:path1/test; 711 export paths:path2/test; 712 } 713 "#, 714 path: ["tests/codegen/path1", "tests/codegen/path2"], 715 }); 716 } 717 } 718