Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 34 additions & 67 deletions components/extract-wit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,76 @@ use std::collections::BTreeMap;
use crate::{
componentized::component::types::{Component, Error},
exports::componentized::component::wit::{
Docs, Enum, EnumCase, Flag, Flags, Function, FunctionKind, Guest, GuestWit, Handle,
IncludeName, Interface, InterfaceId, List, Map, Package, PackageId, PackageName, Param,
Record, RecordField, Result as Result_, Stability, Stable, Tuple, Type, TypeDef,
TypeDefKind, TypeId, TypeOwner, Unstable, Variant, VariantCase, Version, VersionIdentifier,
Wit, World, WorldId, WorldInclude, WorldItem, WorldItemInterface, WorldKey,
Docs, Enum, EnumCase, Flag, Flags, Function, FunctionKind, Guest, Handle, IncludeName,
Interface, InterfaceId, List, Map, Package, PackageId, PackageName, Param, Record,
RecordField, Result as Result_, Stability, Stable, Tuple, Type, TypeDef, TypeDefKind,
TypeId, TypeOwner, Unstable, Variant, VariantCase, Version, VersionIdentifier, Wit, World,
WorldId, WorldInclude, WorldItem, WorldItemInterface, WorldKey,
},
};

pub(crate) struct ExtractWit;

impl Guest for ExtractWit {
type Wit = ExtractedWit;

#[allow(async_fn_in_trait)]
async fn extract(component: &Component) -> Result<(Wit, Package), Error> {
let wasm = component.into_wasm();
let decoded = wit_component::decode(&wasm)?;

let wit = ExtractedWit::new(decoded.resolve());
let package = wit
.package(ExtractedWit::package_id(decoded.package()))
.expect("decoded package must exist");
async fn extract(component: Component) -> Result<Wit, Error> {
let decoded = wit_component::decode(&component)?;

Ok((Wit::new(wit), package))
Wit::new(decoded.resolve(), decoded.package())
}
}

pub(crate) struct ExtractedWit {
worlds: BTreeMap<u32, World>,
interfaces: BTreeMap<u32, Interface>,
types: BTreeMap<u32, TypeDef>,
packages: BTreeMap<u32, Package>,
}

impl ExtractedWit {
fn new(resolve: &wit_parser::Resolve) -> Self {
Self {
impl Wit {
fn new(
resolve: &wit_parser::Resolve,
package_id: wit_parser::PackageId,
) -> Result<Self, Error> {
let wit = Self {
worlds: resolve.worlds.clone().into_iter().fold(
BTreeMap::new(),
|mut worlds, (id, world)| {
worlds.insert(Self::world_id(id).world_id, Self::world(world));
worlds.insert(Self::world_id(id), Self::world(world));
worlds
},
),
interfaces: resolve.interfaces.clone().into_iter().fold(
BTreeMap::new(),
|mut interfaces, (id, interface)| {
interfaces.insert(
Self::interface_id(id).interface_id,
Self::interface(interface),
);
interfaces.insert(Self::interface_id(id), Self::interface(interface));
interfaces
},
),
types: resolve.types.clone().into_iter().fold(
BTreeMap::new(),
|mut types, (id, type_def)| {
types.insert(Self::type_id(id).type_id, Self::type_def(type_def));
types.insert(Self::type_id(id), Self::type_def(type_def));
types
},
),
packages: resolve.packages.clone().into_iter().fold(
BTreeMap::new(),
|mut packages, (id, package)| {
packages.insert(Self::package_id(id).package_id, Self::package(package));
packages.insert(Self::package_id(id), Self::package(package));
packages
},
),

default_package: Some(Self::package_id(package_id)),
};

if wit
.packages
.get(&wit.default_package.clone().unwrap())
.is_none()
{
Err(Error::Other(Some("decoded package must exist".to_string())))?;
}

Ok(wit)
}

fn world_id(id: wit_parser::WorldId) -> WorldId {
WorldId {
world_id: u32::try_from(id.index()).expect("id too large"),
}
WorldId::from(format!("world:{}", id.index()))
}

fn world(world: wit_parser::World) -> World {
Expand Down Expand Up @@ -147,9 +142,7 @@ impl ExtractedWit {
}

fn interface_id(id: wit_parser::InterfaceId) -> InterfaceId {
InterfaceId {
interface_id: u32::try_from(id.index()).expect("id too large"),
}
InterfaceId::from(format!("interface:{}", id.index()))
}

fn interface(interface: wit_parser::Interface) -> Interface {
Expand Down Expand Up @@ -205,9 +198,7 @@ impl ExtractedWit {
}

fn type_id(id: wit_parser::TypeId) -> TypeId {
TypeId {
type_id: u32::try_from(id.index()).expect("id too large"),
}
TypeId::from(format!("type:{}", id.index()))
}

fn type_(type_: wit_parser::Type) -> Type {
Expand Down Expand Up @@ -369,9 +360,7 @@ impl ExtractedWit {
}

fn package_id(id: wit_parser::PackageId) -> PackageId {
PackageId {
package_id: u32::try_from(id.index()).expect("id too large"),
}
PackageId::from(format!("package:{}", id.index()))
}

fn package(package: wit_parser::Package) -> Package {
Expand Down Expand Up @@ -444,28 +433,6 @@ impl ExtractedWit {
}
}

impl GuestWit for ExtractedWit {
#[allow(async_fn_in_trait)]
fn world(&self, id: WorldId) -> Option<World> {
self.worlds.get(&id.world_id).cloned()
}

#[allow(async_fn_in_trait)]
fn interface(&self, id: InterfaceId) -> Option<Interface> {
self.interfaces.get(&id.interface_id).cloned()
}

#[allow(async_fn_in_trait)]
fn type_(&self, id: TypeId) -> Option<TypeDef> {
self.types.get(&id.type_id).cloned()
}

#[allow(async_fn_in_trait)]
fn package(&self, id: PackageId) -> Option<Package> {
self.packages.get(&id.package_id).cloned()
}
}

impl From<anyhow::Error> for Error {
fn from(value: anyhow::Error) -> Self {
Self::Other(Some(value.to_string()))
Expand Down
38 changes: 6 additions & 32 deletions components/wac-loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,57 +3,31 @@
use wac_graph::{types::Package, CompositionGraph, EncodeOptions};

use crate::exports::componentized::component::{
types::{Component, ComponentBorrow, Error, Guest as TypesGuest, GuestComponent},
types::{Component, Error},
wac_loader::Guest,
};

pub(crate) struct WacLoader;

impl TypesGuest for WacLoader {
type Component = WacComponent;
}

impl Guest for WacLoader {
#[allow(async_fn_in_trait)]
async fn plug(
socket: ComponentBorrow<'_>,
plugs: Vec<ComponentBorrow<'_>>,
) -> Result<Component, Error> {
async fn plug(socket: Component, plugs: Vec<Component>) -> Result<Component, Error> {
let mut graph = CompositionGraph::new();

let socket: &WacComponent = socket.get();
let socket = Package::from_bytes("socket", None, socket.into_wasm(), graph.types_mut())?;
let socket = Package::from_bytes("socket", None, socket, graph.types_mut())?;
let socket = graph.register_package(socket)?;

let mut graph_plugs = Vec::new();
for plug in plugs {
let plug: &WacComponent = plug.get();
let plug = Package::from_bytes("plug", None, plug.into_wasm(), graph.types_mut())?;
let plug = Package::from_bytes("plug", None, plug, graph.types_mut())?;
let plug = graph.register_package(plug)?;
graph_plugs.push(plug);
}

wac_graph::plug(&mut graph, graph_plugs, socket)?;
let composed_wasm = graph.encode(EncodeOptions::default())?;

Ok(Component::new(WacComponent::new(composed_wasm)))
}
}
let component = graph.encode(EncodeOptions::default())?;

pub(crate) struct WacComponent {
wasm: Vec<u8>,
}

impl WacComponent {
fn new(wasm: Vec<u8>) -> Self {
Self { wasm }
}
}

impl GuestComponent for WacComponent {
#[allow(async_fn_in_trait)]
fn into_wasm(&self) -> Vec<u8> {
self.wasm.clone()
Ok(component)
}
}

Expand Down
28 changes: 2 additions & 26 deletions components/wasm-loader/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,41 +1,17 @@
#![no_main]

use crate::{
exports::componentized::component::types::{
Component, Error, Guest as TypesGuest, GuestComponent,
},
exports::componentized::component::types::{Component, Error},
exports::componentized::component::wasm_loader::Guest,
};
use wit_bindgen::rt::async_support::StreamReader;

pub(crate) struct WasmLoader;

impl TypesGuest for WasmLoader {
type Component = WasmComponent;
}

impl Guest for WasmLoader {
#[allow(async_fn_in_trait)]
async fn load(wasm: StreamReader<u8>) -> Result<Component, Error> {
let wasm = wasm.collect().await;
Ok(Component::new(WasmComponent::new(wasm)))
}
}

pub(crate) struct WasmComponent {
wasm: Vec<u8>,
}

impl WasmComponent {
fn new(wasm: Vec<u8>) -> Self {
Self { wasm }
}
}

impl GuestComponent for WasmComponent {
#[allow(async_fn_in_trait)]
fn into_wasm(&self) -> Vec<u8> {
self.wasm.clone()
Ok(wasm.collect().await)
}
}

Expand Down
35 changes: 13 additions & 22 deletions components/wit/deps/componentized-component-0.0.0-0/package.wit
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ interface types {
other(option<string>),
}

resource component {
into-wasm: func() -> list<u8>;
}
type component = list<u8>;
}

interface wasm-loader {
Expand Down Expand Up @@ -43,15 +41,13 @@ interface wasm-directory-loader {
interface wac-loader {
use types.{component, error};

plug: async func(socket: borrow<component>, plugs: list<borrow<component>>) -> result<component, error>;
plug: async func(socket: component, plugs: list<component>) -> result<component, error>;
}

interface wit {
use types.{component, error};

record type-id {
type-id: u32,
}
type type-id = string;

variant %type {
%bool,
Expand Down Expand Up @@ -209,13 +205,9 @@ interface wit {
external-id: option<string>,
}

record interface-id {
interface-id: u32,
}
type interface-id = string;

record world-id {
world-id: u32,
}
type world-id = string;

variant type-owner {
%world(world-id),
Expand Down Expand Up @@ -261,9 +253,7 @@ interface wit {
%interface(interface-id),
}

record package-id {
package-id: u32,
}
type package-id = string;

record %interface {
name: option<string>,
Expand Down Expand Up @@ -297,14 +287,15 @@ interface wit {
worlds: list<tuple<string, world-id>>,
}

resource wit {
%interface: func(id: interface-id) -> option<%interface>;
%package: func(id: package-id) -> option<%package>;
%type: func(id: type-id) -> option<type-def>;
%world: func(id: world-id) -> option<%world>;
record wit {
interfaces: map<string, %interface>,
packages: map<string, %package>,
types: map<string, type-def>,
worlds: map<string, %world>,
default-package: option<package-id>,
}

extract: async func(component: borrow<component>) -> result<tuple<wit, %package>, error>;
extract: async func(component: component) -> result<wit, error>;
}

world imports {
Expand Down
1 change: 0 additions & 1 deletion components/wit/worlds.wit
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ world extract-wit {
}

world wac-loader {
import componentized:component/types@0.0.0-0;
export componentized:component/types@0.0.0-0;
export componentized:component/wac-loader@0.0.0-0;
}
Expand Down
2 changes: 1 addition & 1 deletion wit/loader.wit
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ interface wasm-directory-loader {
interface wac-loader {
use types.{component, error};

plug: async func(socket: borrow<component>, plugs: list<borrow<component>>) -> result<component, error>;
plug: async func(socket: component, plugs: list<component>) -> result<component, error>;
}
4 changes: 1 addition & 3 deletions wit/types.wit
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ interface types {
other(option<string>),
}

resource component {
into-wasm: func() -> list<u8>;
}
type component = list<u8>;

}
Loading