# wasm_component_layer
[](https://crates.io/crates/wasm_component_layer)
[](https://docs.rs/wasm_component_layer)
[](https://github.com/rust-secure-code/safety-dance/)
`wasm_component_layer` is a runtime agnostic implementation of the [WebAssembly component model](https://github.com/WebAssembly/component-model).
It supports loading and linking WASM components, inspecting and generating component interface types at runtime, and more atop any WebAssembly backend. The implementation is based upon the [`wasmtime`](https://github.com/bytecodealliance/wasmtime), [`js-component-bindgen`](https://github.com/bytecodealliance/jco), and [`wit-parser`](https://github.com/bytecodealliance/wasm-tools/tree/main) crates.
## Usage
To use `wasm_component_layer`, a runtime is required. The [`wasm_runtime_layer`](https://github.com/DouglasDwyer/wasm_runtime_layer) crate provides the common interface used for WebAssembly runtimes, so when using this crate it must also be added to the `Cargo.toml` file with the appropriate runtime selected. For instance, the examples in this repository use the [`wasmi`](https://github.com/paritytech/wasmi) runtime:
```toml
wasm_component_layer = "0.1.0"
wasm_runtime_layer = { version = "0.1.1", features = [ "backend_wasmi" ] }
```
The following is a small overview of `wasm_component_layer`'s API. The complete example may be found in the [examples folder](/examples). Consider a WASM component with the following WIT:
```wit
package test:guest
interface foo {
// Selects the item in position n within list x
select-nth: func(x: list<string>, n: u32) -> string
}
world guest {
export foo
}
```
The component can be loaded into `wasm_component_layer` and invoked as follows:
```rust
use wasm_component_layer::*;
// The bytes of the component.
const WASM: &[u8] = include_bytes!("single_component/component.wasm");
pub fn main() {
// Create a new engine for instantiating a component.
let engine = Engine::new(wasmi::Engine::default());
// Create a store for managing WASM data and any custom user-defined state.
let mut store = Store::new(&engine, ());
// Parse the component bytes and load its imports and exports.
let component = Component::new(&engine, WASM).unwrap();
// Create a linker that will be used to resolve the component's imports, if any.
let linker = Linker::default();
// Create an instance of the component using the linker.
let instance = linker.instantiate(&mut store, &component).unwrap();
// Get the interface that the interface exports.
let interface = instance.exports().instance(&"test:guest/foo".try_into().unwrap()).unwrap();
// Get the function for selecting a list element.
let select_nth = interface.func("select-nth").unwrap().typed::<(Vec<String>, u32), (String,)>().unwrap();
// Create an example list to test upon.
let example = ["a", "b", "c"].iter().map(ToString::to_string).collect::<Vec<_>>();
println!("Calling select-nth({example:?}, 1) == {}", select_nth.call(&mut store, (example.clone(), 1)).unwrap().0);
// Prints 'Calling select-nth(["a", "b", "c"], 1) == b'
}
```
## Features
`wasm_component_layer` supports the following major features:
- Parsing and instantiating WASM component binaries
- Runtime generation of component interface types
- Specialized list types for faster
- Structural equality of component interface types, as mandated by the spec
- Support for guest resources
- Support for strongly-typed host resources with destructors
The following features have yet to be implemented:
- A macro for generating host bindings
- More comprehensive tests
- Subtyping