wasmtime::component

Derive Macro ComponentType

Source
#[derive(ComponentType)]
{
    // Attributes available to this derive:
    #[component]
}
Available on crate features runtime and component-model only.
Expand description

Derive macro to generate implementations of the ComponentType trait.

This derive macro can be applied to struct and enum definitions and is used to bind either a record, enum, or variant in the component model.

Note you might be looking for bindgen! rather than this macro as that will generate the entire type for you rather than just a trait implementation.

This macro supports a #[component] attribute which is used to customize how the type is bound to the component model. A top-level #[component] attribute is required to specify either record, enum, or variant.

§Records

records in the component model correspond to structs in Rust. An example is:

use wasmtime::component::ComponentType;

#[derive(ComponentType)]
#[component(record)]
struct Color {
    r: u8,
    g: u8,
    b: u8,
}

which corresponds to the WIT type:

record color {
    r: u8,
    g: u8,
    b: u8,
}

Note that the name Color here does not need to match the name in WIT. That’s purely used as a name in Rust of what to refer to. The field names must match that in WIT, however. Field names can be customized with the #[component] attribute though.

use wasmtime::component::ComponentType;

#[derive(ComponentType)]
#[component(record)]
struct VerboseColor {
    #[component(name = "r")]
    red: u8,
    #[component(name = "g")]
    green: u8,
    #[component(name = "b")]
    blue: u8,
}

Also note that field ordering is significant at this time and must match WIT.

§Variants

variants in the component model correspond to a subset of shapes of a Rust enum. Variants in the component model have a single optional payload type which means that not all Rust enums correspond to component model variants. An example variant is:

use wasmtime::component::ComponentType;

#[derive(ComponentType)]
#[component(variant)]
enum Filter {
    #[component(name = "none")]
    None,
    #[component(name = "all")]
    All,
    #[component(name = "some")]
    Some(Vec<String>),
}

which corresponds to the WIT type:

variant filter {
    none,
    all,
    some(list<string>),
}

The variant style of derive allows an optional payload on Rust enum variants but it must be a single unnamed field. Variants of the form Foo(T, U) or Foo { name: T } are not supported at this time.

Note that the order of variants in Rust must match the order of variants in WIT. Additionally it’s likely that #[component(name = "...")] is required on all Rust enum variants because the name currently defaults to the Rust name which is typically UpperCamelCase whereas WIT uses kebab-case.

§Enums

enums in the component model correspond to C-like enums in Rust. Note that a component model enum does not allow any payloads so the Rust enum must additionally have no payloads.

use wasmtime::component::ComponentType;

#[derive(ComponentType)]
#[component(enum)]
#[repr(u8)]
enum Setting {
    #[component(name = "yes")]
    Yes,
    #[component(name = "no")]
    No,
    #[component(name = "auto")]
    Auto,
}

which corresponds to the WIT type:

enum setting {
    yes,
    no,
    auto,
}

Note that the order of variants in Rust must match the order of variants in WIT. Additionally it’s likely that #[component(name = "...")] is required on all Rust enum variants because the name currently defaults to the Rust name which is typically UpperCamelCase whereas WIT uses kebab-case.