Path: blob/main/crates/component-macro/tests/codegen.rs
1692 views
#![allow(dead_code, reason = "lots of macro-generated code")]12macro_rules! gentest {3($id:ident $name:tt $path:tt) => {4mod $id {5mod sugar {6wasmtime::component::bindgen!(in $path);7}8mod async_ {9wasmtime::component::bindgen!({10path: $path,11imports: { default: async },12exports: { default: async },13});14}15mod concurrent {16wasmtime::component::bindgen!({17path: $path,18imports: { default: async | store },19exports: { default: async | store },20});21}22mod tracing {23wasmtime::component::bindgen!({24path: $path,25imports: { default: tracing | verbose_tracing },26exports: { default: tracing | verbose_tracing },27ownership: Borrowing {28duplicate_if_necessary: true29}30});31}32}33};34}3536component_macro_test_helpers::foreach!(gentest);3738mod with_key_and_resources {39use anyhow::Result;40use wasmtime::component::Resource;4142wasmtime::component::bindgen!({43inline: "44package demo:pkg;4546interface bar {47resource a;48resource b;49}5051world foo {52resource a;53resource b;5455import foo: interface {56resource a;57resource b;58}5960import bar;61}62",63with: {64"a": MyA,65"b": MyA,66"foo/a": MyA,67"foo/b": MyA,68"demo:pkg/bar/a": MyA,69"demo:pkg/bar/b": MyA,70},71});7273pub struct MyA;7475struct MyComponent;7677impl FooImports for MyComponent {}7879impl HostA for MyComponent {80fn drop(&mut self, _: Resource<MyA>) -> Result<()> {81loop {}82}83}8485impl HostB for MyComponent {86fn drop(&mut self, _: Resource<MyA>) -> Result<()> {87loop {}88}89}9091impl foo::Host for MyComponent {}9293impl foo::HostA for MyComponent {94fn drop(&mut self, _: Resource<MyA>) -> Result<()> {95loop {}96}97}9899impl foo::HostB for MyComponent {100fn drop(&mut self, _: Resource<MyA>) -> Result<()> {101loop {}102}103}104105impl demo::pkg::bar::Host for MyComponent {}106107impl demo::pkg::bar::HostA for MyComponent {108fn drop(&mut self, _: Resource<MyA>) -> Result<()> {109loop {}110}111}112113impl demo::pkg::bar::HostB for MyComponent {114fn drop(&mut self, _: Resource<MyA>) -> Result<()> {115loop {}116}117}118}119120mod trappable_errors_with_versioned_and_unversioned_packages {121wasmtime::component::bindgen!({122world: "foo:foo/nope",123inline: "124package foo:[email protected];125126interface a {127variant error {128other(string),129}130131f: func() -> result<_, error>;132}133134world foo {135import a;136}137",138path: "tests/codegen/unversioned-foo.wit",139trappable_error_type: {140"foo:foo/[email protected]/error" => MyX,141},142});143144type MyX = u64;145}146147mod trappable_errors {148wasmtime::component::bindgen!({149inline: "150package demo:pkg;151152interface a {153type b = u64;154155z1: func() -> result<_, b>;156z2: func() -> result<_, b>;157}158159interface b {160use a.{b};161z: func() -> result<_, b>;162}163164interface c {165type b = u64;166}167168interface d {169use c.{b};170z: func() -> result<_, b>;171}172173world foo {174import a;175import b;176import d;177}178",179trappable_error_type: {180"demo:pkg/a/b" => MyX,181"demo:pkg/c/b" => MyX,182},183});184185type MyX = u32;186}187188mod interface_name_with_rust_keyword {189wasmtime::component::bindgen!({190inline: "191package foo:foo;192193interface crate { }194195world foo {196export crate;197}198"199});200}201202mod with_works_with_hierarchy {203mod bindings {204wasmtime::component::bindgen!({205inline: "206package foo:foo;207208interface a {209record t {210x: u32,211}212x: func() -> t;213}214215interface b {216use a.{t};217x: func() -> t;218}219220interface c {221use b.{t};222x: func() -> t;223}224225world foo {226import c;227}228"229});230}231232mod with_just_one_interface {233wasmtime::component::bindgen!({234inline: "235package foo:foo;236237interface a {238record t {239x: u32,240}241x: func() -> t;242}243244interface b {245use a.{t};246x: func() -> t;247}248249interface c {250use b.{t};251x: func() -> t;252}253254world foo {255use c.{t};256257import x: func() -> t;258}259",260with: { "foo:foo/a": super::bindings::foo::foo::a }261});262263struct X;264265impl FooImports for X {266fn x(&mut self) -> super::bindings::foo::foo::a::T {267loop {}268}269}270}271272mod with_whole_package {273wasmtime::component::bindgen!({274inline: "275package foo:foo;276277interface a {278record t {279x: u32,280}281x: func() -> t;282}283284interface b {285use a.{t};286x: func() -> t;287}288289interface c {290use b.{t};291x: func() -> t;292}293294world foo {295use c.{t};296297import x: func() -> t;298}299",300with: { "foo:foo": super::bindings::foo::foo }301});302303struct X;304305impl FooImports for X {306fn x(&mut self) -> super::bindings::foo::foo::a::T {307loop {}308}309}310}311312mod with_whole_namespace {313wasmtime::component::bindgen!({314inline: "315package foo:foo;316317interface a {318record t {319x: u32,320}321x: func() -> t;322}323324interface b {325use a.{t};326x: func() -> t;327}328329interface c {330use b.{t};331x: func() -> t;332}333334world foo {335use c.{t};336337import x: func() -> t;338}339",340with: { "foo": super::bindings::foo }341});342343struct X;344345impl FooImports for X {346fn x(&mut self) -> super::bindings::foo::foo::a::T {347loop {}348}349}350}351}352353mod trappable_imports {354mod none {355wasmtime::component::bindgen!({356inline: "357package foo:foo;358359world foo {360import foo: func();361}362",363});364struct X;365366impl FooImports for X {367fn foo(&mut self) {}368}369}370371mod all {372wasmtime::component::bindgen!({373inline: "374package foo:foo;375376world foo {377import foo: func();378}379",380imports: { default: trappable },381});382struct X;383384impl FooImports for X {385fn foo(&mut self) -> wasmtime::Result<()> {386Ok(())387}388}389}390391mod some {392wasmtime::component::bindgen!({393inline: "394package foo:foo;395396world foo {397import foo: func();398import bar: func();399}400",401imports: { "foo": trappable },402});403struct X;404405impl FooImports for X {406fn foo(&mut self) -> wasmtime::Result<()> {407Ok(())408}409fn bar(&mut self) {}410}411}412413mod across_interfaces {414use wasmtime::component::Resource;415416wasmtime::component::bindgen!({417inline: "418package foo:foo;419420interface a {421foo: func();422bar: func();423424resource r {425constructor();426foo: func();427bar: static func();428}429}430431world foo {432import a;433import foo: func();434import bar: func();435import i: interface {436foo: func();437bar: func();438}439440}441",442imports: {443"foo": trappable | exact,444"i/foo": trappable,445"foo:foo/a/foo": trappable,446},447with: { "foo:foo/a/r": R },448});449450struct X;451pub struct R;452453impl FooImports for X {454fn foo(&mut self) -> wasmtime::Result<()> {455Ok(())456}457fn bar(&mut self) {}458}459460impl i::Host for X {461fn foo(&mut self) -> wasmtime::Result<()> {462Ok(())463}464fn bar(&mut self) {}465}466467impl foo::foo::a::Host for X {468fn foo(&mut self) -> wasmtime::Result<()> {469Ok(())470}471fn bar(&mut self) {}472}473474impl foo::foo::a::HostR for X {475fn new(&mut self) -> Resource<R> {476loop {}477}478fn foo(&mut self, _: Resource<R>) {}479fn bar(&mut self) {}480fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> {481Ok(())482}483}484}485486mod resources {487use wasmtime::component::Resource;488489wasmtime::component::bindgen!({490inline: "491package foo:foo;492493interface a {494resource r {495constructor();496foo: func();497bar: static func();498}499}500501world foo {502import a;503504}505",506imports: {507"foo:foo/a/[constructor]r": trappable,508"foo:foo/a/[method]r.foo": trappable,509"foo:foo/a/[static]r.bar": trappable,510},511with: { "foo:foo/a/r": R },512});513514struct X;515pub struct R;516517impl foo::foo::a::Host for X {}518519impl foo::foo::a::HostR for X {520fn new(&mut self) -> wasmtime::Result<Resource<R>> {521loop {}522}523fn foo(&mut self, _: Resource<R>) -> wasmtime::Result<()> {524Ok(())525}526fn bar(&mut self) -> wasmtime::Result<()> {527Ok(())528}529fn drop(&mut self, _: Resource<R>) -> wasmtime::Result<()> {530Ok(())531}532}533}534}535536mod custom_derives {537use std::collections::{HashSet, hash_map::RandomState};538539wasmtime::component::bindgen!({540inline: "541package my:inline;542543interface blah {544variant abc {545a,546b,547c548}549550record foo {551field1: string,552field2: list<u32>,553field3: abc554}555556bar: func(cool: foo);557}558559world baz {560import blah;561}562",563// Clone is included by default almost everywhere, so include it here to make sure it564// doesn't conflict565additional_derives: [serde::Serialize, serde::Deserialize, Hash, Clone, PartialEq, Eq],566});567568use my::inline::blah::{Abc, Foo, Host};569570struct X;571572impl Host for X {573fn bar(&mut self, cool: Foo) {574// Check that built in derives that I've added actually work by seeing that this hashes575let _blah: HashSet<Foo, RandomState> = HashSet::from_iter([Foo {576field1: "hello".to_string(),577field2: vec![1, 2, 3],578field3: Abc::B,579}]);580581// Check that the attributes from an external crate actually work. If they don't work,582// compilation will fail here583let _ = serde_json::to_string(&cool);584}585}586}587588mod with_and_mixing_async {589mod with_async {590wasmtime::component::bindgen!({591inline: "592package my:inline;593interface foo {594type t = u32;595foo: func() -> t;596}597interface bar {598use foo.{t};599bar: func() -> t;600}601world x {602import bar;603}604",605imports: {606"my:inline/bar/bar": async,607},608});609}610611mod without_async {612wasmtime::component::bindgen!({613inline: "614package my:inline;615interface foo {616type t = u32;617foo: func() -> t;618}619interface bar {620use foo.{t};621bar: func() -> t;622}623world x {624import bar;625}626",627with: {628"my:inline/foo": super::with_async::my::inline::foo,629},630require_store_data_send: true,631});632}633634mod third {635wasmtime::component::bindgen!({636inline: "637package my:inline;638interface foo {639type t = u32;640foo: func() -> t;641}642interface bar {643use foo.{t};644bar: func() -> t;645}646interface baz {647use bar.{t};648baz: func() -> t;649}650world x {651import baz;652}653",654with: {655"my:inline/foo": super::with_async::my::inline::foo,656"my:inline/bar": super::without_async::my::inline::bar,657},658require_store_data_send: true,659});660}661}662663mod trappable_error_type_and_versions {664struct MyError;665666mod package_no_version_path_no_version {667wasmtime::component::bindgen!({668inline: "669package my:inline;670interface i {671enum e { a, b, c }672}673world foo {}674",675trappable_error_type: {676"my:inline/i/e" => super::MyError,677},678});679}680mod package_version_path_no_version {681wasmtime::component::bindgen!({682inline: "683package my:[email protected];684interface i {685enum e { a, b, c }686}687world foo {}688",689trappable_error_type: {690"my:inline/i/e" => super::MyError,691},692});693}694mod package_version_path_version {695wasmtime::component::bindgen!({696inline: "697package my:[email protected];698interface i {699enum e { a, b, c }700}701world foo {}702",703trappable_error_type: {704"my:inline/[email protected]/e" => super::MyError,705},706});707}708}709710mod paths {711mod multiple_paths {712wasmtime::component::bindgen!({713world: "test:paths/test",714inline: r#"715package test:paths;716world test {717import paths:path1/test;718export paths:path2/test;719}720"#,721path: ["tests/codegen/path1", "tests/codegen/path2"],722});723}724}725726727