Skip to main content

wit_component/
targets.rs

1use crate::encoding::encode_world;
2use anyhow::{Context, Result};
3use wasm_encoder::{ComponentBuilder, ComponentExportKind, ComponentTypeRef};
4use wasmparser::{Validator, WasmFeatures};
5use wit_parser::{Resolve, WorldId};
6
7/// This function checks whether `component_to_test` correctly conforms to the world specified.
8/// It does so by instantiating a generated component that imports a component instance with
9/// the component type as described by the "target" world.
10pub fn targets(
11    resolve: &Resolve,
12    world: WorldId,
13    component_to_test: &[u8],
14    canonical_names: bool,
15) -> Result<()> {
16    let mut root_component = ComponentBuilder::default();
17
18    // (1) Embed the component to test.
19    let component_to_test_idx = root_component.component_raw(None, component_to_test);
20
21    // (2) Encode the world to a component type and embed a new component which
22    // imports the encoded component type.
23    let test_component_idx = {
24        let component_ty = encode_world(resolve, world, canonical_names)?;
25        let mut component = ComponentBuilder::default();
26        let component_ty_idx = component.type_component(None, &component_ty);
27        component.import(
28            &resolve.worlds[world].name,
29            ComponentTypeRef::Component(component_ty_idx),
30        );
31        root_component.component(None, component)
32    };
33
34    // (3) Instantiate the component from (2) with the component to test from (1).
35    let args: Vec<(String, ComponentExportKind, u32)> = vec![(
36        resolve.worlds[world].name.clone(),
37        ComponentExportKind::Component,
38        component_to_test_idx,
39    )];
40    root_component.instantiate(None, test_component_idx, args);
41
42    let bytes = root_component.finish();
43
44    Validator::new_with_features(WasmFeatures::all())
45        .validate_all(&bytes)
46        .context("failed to validate encoded bytes")?;
47
48    Ok(())
49}