Skip to main content

ComponentType

Derive Macro ComponentType 

Source
#[derive(ComponentType)]
{
    // Attributes available to this derive:
    #[component]
}
Available on crate features component-model and runtime 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.