diff --git a/WRAP_TEST_HARNESS b/WRAP_TEST_HARNESS index 8b25206ff9..db8b214f7a 100644 --- a/WRAP_TEST_HARNESS +++ b/WRAP_TEST_HARNESS @@ -1 +1 @@ -master \ No newline at end of file +module-trait-rs \ No newline at end of file diff --git a/packages/js/client/src/__tests__/core/type-test-cases.ts b/packages/js/client/src/__tests__/core/type-test-cases.ts index 57cfc9a18f..ba2c28b021 100644 --- a/packages/js/client/src/__tests__/core/type-test-cases.ts +++ b/packages/js/client/src/__tests__/core/type-test-cases.ts @@ -690,9 +690,9 @@ export const typeTestCases = (implementation: string) => { }, ]); - const method5 = await client.invoke({ + const method4 = await client.invoke({ uri, - method: "method5", + method: "method4", args: { arg: { prop: [49, 50, 51, 52], @@ -700,9 +700,9 @@ export const typeTestCases = (implementation: string) => { }, }); - if (!method5.ok) fail(method5.error); - expect(method5.value).toBeTruthy(); - expect(method5.value).toEqual({ + if (!method4.ok) fail(method4.error); + expect(method4.value).toBeTruthy(); + expect(method4.value).toEqual({ prop: "1234", nested: { prop: "nested prop", diff --git a/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.build.yaml b/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.build.yaml new file mode 100644 index 0000000000..6e5d4c2c8a --- /dev/null +++ b/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.build.yaml @@ -0,0 +1,4 @@ +format: 0.2.0 +linked_packages: + - name: "polywrap-wasm-rs" + path: ../../../../../../wasm/rs/ \ No newline at end of file diff --git a/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.yaml b/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.yaml index f31ecde3a7..752f451f1d 100644 --- a/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.yaml +++ b/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/polywrap.yaml @@ -5,3 +5,5 @@ project: source: module: ./Cargo.toml schema: ./polywrap.graphql +extensions: + build: ./polywrap.build.yaml diff --git a/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/src/lib.rs b/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/src/lib.rs index 0af424907f..1a5d73bd42 100644 --- a/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/src/lib.rs +++ b/packages/js/uri-resolver-extensions/src/__tests__/wrappers/test-resolver/src/lib.rs @@ -1,30 +1,39 @@ pub mod wrap; use wrap::{ *, + env::{Env}, imported::{ ArgsGetFile, ArgsTryResolveUri, } }; -pub fn try_resolve_uri(args: ArgsTryResolveUri, _env: Option) -> Option { - if args.authority != "test" { - return None; - } - - match args.path.as_str() { - "from" => Some(UriResolverMaybeUriOrManifest { - manifest: None, - uri: Some("test/to".to_string()) - }), - "package" => Some(UriResolverMaybeUriOrManifest { - manifest: Some(vec![0]), - uri: None - }), - "error" => panic!("Test error"), - _ => None +impl ModuleTrait for Module { + fn try_resolve_uri( + args: ArgsTryResolveUri, + _env: Option + ) -> Result, String> { + if args.authority != "test" { + return Ok(None); + } + + match args.path.as_str() { + "from" => Ok(Some(UriResolverMaybeUriOrManifest { + manifest: None, + uri: Some("test/to".to_string()) + })), + "package" => Ok(Some(UriResolverMaybeUriOrManifest { + manifest: Some(vec![0]), + uri: None + })), + "error" => Err("Test error".to_string()), + _ => Ok(None) + } } -} -pub fn get_file(_args: ArgsGetFile, _env: Option) -> Option> { - return None; -} + fn get_file( + _args: ArgsGetFile, + _env: Option + ) -> Result>, String> { + return Ok(None); + } +} \ No newline at end of file diff --git a/packages/schema/bind/src/bindings/rust/plugin/index.ts b/packages/schema/bind/src/bindings/rust/plugin/index.ts index e8ab399913..180a40ccdd 100644 --- a/packages/schema/bind/src/bindings/rust/plugin/index.ts +++ b/packages/schema/bind/src/bindings/rust/plugin/index.ts @@ -1,4 +1,4 @@ -import * as Transforms from "./transforms"; +import * as Transforms from "../transforms"; import { Functions } from "../"; import { GenerateBindingFn, renderTemplates } from "../.."; import { BindOptions, BindOutput } from "../../.."; diff --git a/packages/schema/bind/src/bindings/rust/plugin/transforms/byRef.ts b/packages/schema/bind/src/bindings/rust/transforms/byRef.ts similarity index 100% rename from packages/schema/bind/src/bindings/rust/plugin/transforms/byRef.ts rename to packages/schema/bind/src/bindings/rust/transforms/byRef.ts diff --git a/packages/schema/bind/src/bindings/rust/plugin/transforms/index.ts b/packages/schema/bind/src/bindings/rust/transforms/index.ts similarity index 100% rename from packages/schema/bind/src/bindings/rust/plugin/transforms/index.ts rename to packages/schema/bind/src/bindings/rust/transforms/index.ts diff --git a/packages/schema/bind/src/bindings/rust/plugin/transforms/propertyDeps.ts b/packages/schema/bind/src/bindings/rust/transforms/propertyDeps.ts similarity index 92% rename from packages/schema/bind/src/bindings/rust/plugin/transforms/propertyDeps.ts rename to packages/schema/bind/src/bindings/rust/transforms/propertyDeps.ts index 793ef1f641..b65de228ad 100644 --- a/packages/schema/bind/src/bindings/rust/plugin/transforms/propertyDeps.ts +++ b/packages/schema/bind/src/bindings/rust/transforms/propertyDeps.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable no-useless-escape */ -import { isBaseType, isBuiltInType } from "../../types"; +import { isBaseType, isBuiltInType } from "../types"; import { ImportedModuleDefinition, @@ -8,6 +8,7 @@ import { AnyDefinition, ModuleDefinition, EnvDefinition, + Abi, } from "@polywrap/wrap-manifest-types-js"; import { AbiTransforms } from "@polywrap/schema-parse"; @@ -18,6 +19,7 @@ interface PropertyDep { } interface PropertyDepsState { + abiEnvDefinition?: EnvDefinition; envDefinition?: EnvDefinition; objectDefinition?: ObjectDefinition; moduleDefinition?: ModuleDefinition; @@ -30,6 +32,12 @@ export function propertyDeps(): AbiTransforms { return { enter: { + Abi: (abi: Abi) => { + if (abi.envType) { + state.abiEnvDefinition = abi.envType; + } + return abi; + }, EnvDefinition: (def: EnvDefinition) => { state.envDefinition = def; state.propertyDeps = []; @@ -43,6 +51,13 @@ export function propertyDeps(): AbiTransforms { ModuleDefinition: (def: ModuleDefinition) => { state.moduleDefinition = def; state.propertyDeps = []; + if (state.abiEnvDefinition) { + state.propertyDeps.push({ + crate: "crate", + type: "Env", + isEnum: false, + }); + } return def; }, ImportedModuleDefinition: (def: ImportedModuleDefinition) => { diff --git a/packages/schema/bind/src/bindings/rust/wasm/index.ts b/packages/schema/bind/src/bindings/rust/wasm/index.ts index 6fcb91eeb2..ff7fdcc617 100644 --- a/packages/schema/bind/src/bindings/rust/wasm/index.ts +++ b/packages/schema/bind/src/bindings/rust/wasm/index.ts @@ -1,4 +1,4 @@ -import * as Transforms from "./transforms"; +import * as Transforms from "../transforms"; import { Functions } from "../"; import { GenerateBindingFn, renderTemplates } from "../.."; import { loadSubTemplates } from "../../utils"; diff --git a/packages/schema/bind/src/bindings/rust/wasm/templates/entry-rs.mustache b/packages/schema/bind/src/bindings/rust/wasm/templates/entry-rs.mustache index 5e23b926cc..4287286a50 100644 --- a/packages/schema/bind/src/bindings/rust/wasm/templates/entry-rs.mustache +++ b/packages/schema/bind/src/bindings/rust/wasm/templates/entry-rs.mustache @@ -12,6 +12,7 @@ use polywrap_wasm_rs::{ invoke, InvokeArgs, }; +use crate::module::Module; #[no_mangle] pub extern "C" fn _wrap_invoke(method_size: u32, args_size: u32, env_size: u32) -> bool { @@ -19,13 +20,21 @@ pub extern "C" fn _wrap_invoke(method_size: u32, args_size: u32, env_size: u32) abort::wrap_abort_setup(); let args: InvokeArgs = invoke::wrap_invoke_args(method_size, args_size); + let result: Vec; match args.method.as_str() { {{#moduleType}} {{#methods}} - "{{name}}" => invoke::wrap_invoke(args, env_size, Some({{#toLower}}{{name}}{{/toLower}}_wrapped)), + "{{name}}" => { + result = {{#toLower}}{{name}}{{/toLower}}_wrapped(args.args.as_slice(), env_size); + } {{/methods}} {{/moduleType}} - _ => invoke::wrap_invoke(args, env_size, None), - } + _ => { + invoke::wrap_invoke_error(format!("Could not find invoke function {}", args.method)); + return false; + } + }; + invoke::wrap_invoke_result(result); + return true; } diff --git a/packages/schema/bind/src/bindings/rust/wasm/templates/mod-rs.mustache b/packages/schema/bind/src/bindings/rust/wasm/templates/mod-rs.mustache index e532fa3b78..4995ae44f4 100644 --- a/packages/schema/bind/src/bindings/rust/wasm/templates/mod-rs.mustache +++ b/packages/schema/bind/src/bindings/rust/wasm/templates/mod-rs.mustache @@ -43,6 +43,8 @@ pub use {{#detectKeyword}}{{#toLower}}{{namespace}}{{/toLower}}{{/detectKeyword} {{#moduleType}} pub mod {{#detectKeyword}}{{#toLower}}{{type}}{{/toLower}}{{/detectKeyword}}; pub use {{#detectKeyword}}{{#toLower}}{{type}}{{/toLower}}{{/detectKeyword}}::{ + Module, + ModuleTrait, {{#methods}} deserialize_{{#toLower}}{{name}}{{/toLower}}_args, serialize_{{#toLower}}{{name}}{{/toLower}}_result, diff --git a/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/mod-rs.mustache b/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/mod-rs.mustache index 40ff6b6559..ed7476933f 100644 --- a/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/mod-rs.mustache +++ b/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/mod-rs.mustache @@ -15,4 +15,7 @@ pub use serialization::{ {{/methods}} }; {{/methods.length}} + +pub mod module; +pub use module::*; {{/moduleType}} \ No newline at end of file diff --git a/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/module-rs.mustache b/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/module-rs.mustache new file mode 100644 index 0000000000..1e4490872b --- /dev/null +++ b/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/module-rs.mustache @@ -0,0 +1,37 @@ +{{#moduleType}} +use crate::{ + {{#methods}} + Args{{#toUpper}}{{name}}{{/toUpper}}, + {{/methods}} +}; +use polywrap_wasm_rs::{ + BigInt, + BigNumber, + Map, + JSON, +}; +{{#propertyDeps.length}} + +{{#propertyDeps}} +{{^isEnum}} +use {{crate}}::{{#detectKeyword}}{{#toUpper}}{{type}}{{/toUpper}}{{/detectKeyword}}; +{{/isEnum}} +{{#isEnum}} +use crate::{ + {{#detectKeyword}}{{#toUpper}}{{type}}{{/toUpper}}{{/detectKeyword}}, +}; +{{/isEnum}} +{{/propertyDeps}} +{{/propertyDeps.length}} + +pub struct Module; + +pub trait ModuleTrait { + {{#methods}} + fn {{#detectKeyword}}{{#toLower}}{{name}}{{/toLower}}{{/detectKeyword}}(args: Args{{#toUpper}}{{name}}{{/toUpper}}{{#env}}, env: {{#required}}Env{{/required}}{{^required}}Option{{/required}}{{/env}}) -> Result<{{#return}}{{#toWasm}}{{toGraphQLType}}{{/toWasm}}{{/return}}, String>; + {{^last}} + + {{/last}} + {{/methods}} +} +{{/moduleType}} \ No newline at end of file diff --git a/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/wrapped-rs.mustache b/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/wrapped-rs.mustache index 0152116543..f82fac494f 100644 --- a/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/wrapped-rs.mustache +++ b/packages/schema/bind/src/bindings/rust/wasm/templates/module-type/wrapped-rs.mustache @@ -6,20 +6,18 @@ use polywrap_wasm_rs::{ use crate::{ {{#methods}} - {{#detectKeyword}}{{#toLower}}{{name}}{{/toLower}}{{/detectKeyword}}, Args{{#toUpper}}{{name}}{{/toUpper}}, deserialize_{{#toLower}}{{name}}{{/toLower}}_args, serialize_{{#toLower}}{{name}}{{/toLower}}_result{{^last}},{{/last}} {{/methods}} }; {{/methods.length}} -{{/moduleType}} +use crate::module::{ModuleTrait, Module}; {{#envType}} use crate::Env; {{/envType}} -{{#moduleType}} {{#methods}} pub fn {{#toLower}}{{name}}{{/toLower}}_wrapped(args: &[u8], env_size: u32) -> Vec { {{#env}} @@ -34,7 +32,6 @@ pub fn {{#toLower}}{{name}}{{/toLower}}_wrapped(args: &[u8], env_size: u32) -> V {{/required}} {{^required}} let mut env: Option = None; - if env_size > 0 { let env_buf = wrap_load_env(env_size); env = Some(Env::from_buffer(&env_buf).unwrap()); @@ -46,12 +43,19 @@ pub fn {{#toLower}}{{name}}{{/toLower}}_wrapped(args: &[u8], env_size: u32) -> V match deserialize_{{#toLower}}{{name}}{{/toLower}}_args(args) { Ok(args) => { {{/arguments.length}} - let result = {{#detectKeyword}}{{#toLower}}{{name}}{{/toLower}}{{/detectKeyword}}(Args{{#toUpper}}{{name}}{{/toUpper}} { + let result = Module::{{#detectKeyword}}{{#toLower}}{{name}}{{/toLower}}{{/detectKeyword}}(Args{{#toUpper}}{{name}}{{/toUpper}} { {{#arguments}} {{#detectKeyword}}{{#toLower}}{{name}}{{/toLower}}{{/detectKeyword}}: args.{{#detectKeyword}}{{#toLower}}{{name}}{{/toLower}}{{/detectKeyword}}, {{/arguments}} }{{#env}}, env{{/env}}); - serialize_{{#toLower}}{{name}}{{/toLower}}_result({{#return}}&{{/return}}result).unwrap() + match result { + Ok(res) => { + serialize_{{#toLower}}{{name}}{{/toLower}}_result({{#return}}&{{/return}}res).unwrap() + } + Err(e) => { + panic!("{}", e.to_string()) + } + } {{#arguments.length}} } Err(e) => { diff --git a/packages/schema/bind/src/bindings/rust/wasm/transforms/byRef.ts b/packages/schema/bind/src/bindings/rust/wasm/transforms/byRef.ts deleted file mode 100644 index b5f87a673c..0000000000 --- a/packages/schema/bind/src/bindings/rust/wasm/transforms/byRef.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { AbiTransforms } from "@polywrap/schema-parse"; -import { AnyDefinition } from "@polywrap/wrap-manifest-types-js"; - -export function byRef(): AbiTransforms { - return { - enter: { - // eslint-disable-next-line @typescript-eslint/naming-convention - AnyDefinition: (def: AnyDefinition) => { - const byRefScalars = ["String", "BigInt", "BigNumber", "Map", "Bytes"]; - - if (def.scalar) { - if (byRefScalars.indexOf(def.scalar.type) > -1 || !def.required) { - return { - ...def, - byRef: true, - }; - } - } - - return def; - }, - }, - }; -} diff --git a/packages/schema/bind/src/bindings/rust/wasm/transforms/index.ts b/packages/schema/bind/src/bindings/rust/wasm/transforms/index.ts deleted file mode 100644 index 56b11478c3..0000000000 --- a/packages/schema/bind/src/bindings/rust/wasm/transforms/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./byRef"; -export * from "./propertyDeps"; diff --git a/packages/schema/bind/src/bindings/rust/wasm/transforms/propertyDeps.ts b/packages/schema/bind/src/bindings/rust/wasm/transforms/propertyDeps.ts deleted file mode 100644 index 793ef1f641..0000000000 --- a/packages/schema/bind/src/bindings/rust/wasm/transforms/propertyDeps.ts +++ /dev/null @@ -1,171 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/* eslint-disable no-useless-escape */ -import { isBaseType, isBuiltInType } from "../../types"; - -import { - ImportedModuleDefinition, - ObjectDefinition, - AnyDefinition, - ModuleDefinition, - EnvDefinition, -} from "@polywrap/wrap-manifest-types-js"; -import { AbiTransforms } from "@polywrap/schema-parse"; - -interface PropertyDep { - crate: string; - type: string; - isEnum: boolean; -} - -interface PropertyDepsState { - envDefinition?: EnvDefinition; - objectDefinition?: ObjectDefinition; - moduleDefinition?: ModuleDefinition; - importedModuleDefinition?: ImportedModuleDefinition; - propertyDeps?: PropertyDep[]; -} - -export function propertyDeps(): AbiTransforms { - const state: PropertyDepsState = {}; - - return { - enter: { - EnvDefinition: (def: EnvDefinition) => { - state.envDefinition = def; - state.propertyDeps = []; - return def; - }, - ObjectDefinition: (def: ObjectDefinition) => { - state.objectDefinition = def; - state.propertyDeps = []; - return def; - }, - ModuleDefinition: (def: ModuleDefinition) => { - state.moduleDefinition = def; - state.propertyDeps = []; - return def; - }, - ImportedModuleDefinition: (def: ImportedModuleDefinition) => { - state.importedModuleDefinition = def; - state.propertyDeps = []; - return def; - }, - AnyDefinition: (def: AnyDefinition) => { - const appendPropertyDep = ( - rootType: string, - array: PropertyDep[] - ): PropertyDep[] => { - let typeName = def.type; - - if (typeName.indexOf("[") === 0) { - typeName = typeName.replace(/\[|\]|\!|\?/g, ""); - } - - const appendUnique = (item: PropertyDep) => { - if ( - array.findIndex( - (i) => i.crate === item.crate && i.type === item.type - ) === -1 - ) { - array.push(item); - } - }; - - const isKnownType = (name: string) => - isBaseType(name) || isBuiltInType(name) || name === rootType; - - // if type is map and the value is custom, - // we need to add it into property dependency - if (typeName.startsWith("Map<")) { - const valueName = def.map?.object?.type ?? def.map?.enum?.type; - if (valueName && !isKnownType(valueName)) { - appendUnique({ - crate: "crate", - type: valueName, - isEnum: valueName === def.map?.enum?.type, - }); - - return array; - } - - return array; - } - - if (isKnownType(typeName)) { - return array; - } - - appendUnique({ - crate: "crate", - type: typeName, - isEnum: !!def.enum || !!def.array?.enum, - }); - - return array; - }; - - if (state.envDefinition && state.propertyDeps) { - state.propertyDeps = appendPropertyDep( - state.envDefinition.type, - state.propertyDeps - ); - } else if (state.objectDefinition && state.propertyDeps) { - state.propertyDeps = appendPropertyDep( - state.objectDefinition.type, - state.propertyDeps - ); - } else if (state.moduleDefinition && state.propertyDeps) { - state.propertyDeps = appendPropertyDep( - state.moduleDefinition.type, - state.propertyDeps - ); - } else if (state.importedModuleDefinition && state.propertyDeps) { - state.propertyDeps = appendPropertyDep( - state.importedModuleDefinition.type, - state.propertyDeps - ); - } - - return def; - }, - }, - leave: { - EnvDefinition: (def: EnvDefinition) => { - const propertyDeps = state.propertyDeps; - state.propertyDeps = undefined; - state.envDefinition = undefined; - return { - ...def, - propertyDeps, - }; - }, - ObjectDefinition: (def: ObjectDefinition) => { - const propertyDeps = state.propertyDeps; - state.propertyDeps = undefined; - state.objectDefinition = undefined; - return { - ...def, - propertyDeps, - }; - }, - ModuleDefinition: (def: ModuleDefinition) => { - const propertyDeps = state.propertyDeps; - state.propertyDeps = undefined; - state.moduleDefinition = undefined; - return { - ...def, - propertyDeps, - }; - }, - ImportedModuleDefinition: (def: ImportedModuleDefinition) => { - const propertyDeps = state.propertyDeps; - state.propertyDeps = undefined; - state.importedModuleDefinition = undefined; - return { - ...def, - propertyDeps, - }; - }, - }, - }; -} diff --git a/packages/templates/package.json b/packages/templates/package.json index 39fb0e2390..5eb0b7b4ce 100644 --- a/packages/templates/package.json +++ b/packages/templates/package.json @@ -8,9 +8,8 @@ "url": "https://github.com/polywrap/monorepo.git" }, "scripts": { - "wasm-linked:up": "cp ./polywrap.wasm-linked* ./wasm/assemblyscript/", - "wasm-linked:down": "rm ./wasm/assemblyscript/polywrap.wasm-linked*", - "test": "yarn wasm-linked:up && jest --passWithNoTests --runInBand --verbose && yarn wasm-linked:down" + "test": "jest --passWithNoTests --runInBand --verbose", + "test:ci": "yarn test" }, "devDependencies": { "@types/jest": "26.0.8", diff --git a/packages/templates/polywrap.wasm-linked.build.yaml b/packages/templates/polywrap.wasm-assemblyscript-linked.build.yaml similarity index 100% rename from packages/templates/polywrap.wasm-linked.build.yaml rename to packages/templates/polywrap.wasm-assemblyscript-linked.build.yaml diff --git a/packages/templates/polywrap.wasm-linked.yaml b/packages/templates/polywrap.wasm-assemblyscript-linked.yaml similarity index 72% rename from packages/templates/polywrap.wasm-linked.yaml rename to packages/templates/polywrap.wasm-assemblyscript-linked.yaml index 06c9f04803..4d7440dad2 100644 --- a/packages/templates/polywrap.wasm-linked.yaml +++ b/packages/templates/polywrap.wasm-assemblyscript-linked.yaml @@ -6,4 +6,4 @@ source: module: ./src/index.ts schema: ./src/schema.graphql extensions: - build: ./polywrap.wasm-linked.build.yaml + build: ./polywrap.wasm-assemblyscript-linked.build.yaml diff --git a/packages/templates/polywrap.wasm-rust-linked.build.yaml b/packages/templates/polywrap.wasm-rust-linked.build.yaml new file mode 100644 index 0000000000..5f7bec2c9e --- /dev/null +++ b/packages/templates/polywrap.wasm-rust-linked.build.yaml @@ -0,0 +1,7 @@ +format: 0.2.0 +strategies: + image: + name: template-wasm-rs +linked_packages: + - name: "polywrap-wasm-rs" + path: ../../../wasm/rs \ No newline at end of file diff --git a/packages/templates/polywrap.wasm-rust-linked.yaml b/packages/templates/polywrap.wasm-rust-linked.yaml new file mode 100644 index 0000000000..0777453ddd --- /dev/null +++ b/packages/templates/polywrap.wasm-rust-linked.yaml @@ -0,0 +1,9 @@ +format: 0.3.0 +project: + name: template-wasm-rs + type: wasm/rust +source: + module: ./Cargo.toml + schema: ./src/schema.graphql +extensions: + build: ./polywrap.wasm-rust-linked.build.yaml diff --git a/packages/templates/tests.spec.ts b/packages/templates/tests.spec.ts index e51690b8e5..c669e2a9e8 100644 --- a/packages/templates/tests.spec.ts +++ b/packages/templates/tests.spec.ts @@ -1,6 +1,6 @@ import fs from "fs"; import path from "path"; -import { exec } from "child_process"; +import { exec, execSync } from "child_process"; jest.setTimeout(800000); @@ -15,12 +15,12 @@ describe("Templates", () => { typescript: { build: "yarn build", test: "yarn test" }, assemblyscript: { codegen: "yarn codegen", - build: "npx polywrap build -m ./polywrap.wasm-linked.yaml", + build: "npx polywrap build -m ./polywrap.wasm-assemblyscript-linked.yaml", test: "yarn test", }, rust: { codegen: "yarn codegen", - build: "yarn build", + build: "yarn build -m ./polywrap.wasm-rust-linked.yaml", test: "yarn test", }, interface: { build: "yarn build" }, @@ -68,6 +68,53 @@ describe("Templates", () => { ); } + let originalCargoFile: string; + let cargoFilePath: string; + + beforeAll(() => { + // Copy test configs + if (projectType === "wasm" && language !== "interface") { + execSync( + `cp ${rootDir}/polywrap.${projectType}-${language}-linked* ${rootDir}/${projectType}/${language}/` + ); + + if (language === "rust") { + cargoFilePath = path.join( + rootDir, + projectType, + language, + "Cargo.toml" + ); + + originalCargoFile = fs.readFileSync(cargoFilePath, { + encoding: "utf-8", + }); + const cargoFile = originalCargoFile.replace( + /polywrap-wasm-rs = \{ version = "0.1.0" \}/, + `polywrap-wasm-rs = { path = "${path.join( + rootDir, + "..", + "wasm", + "rs" + )}" }` + ); + fs.writeFileSync(cargoFilePath, cargoFile); + } + } + }); + + afterAll(() => { + // Remove test configs + if (projectType === "wasm" && language !== "interface") { + if (language === "rust") { + fs.writeFileSync(cargoFilePath, originalCargoFile); + } + execSync( + `rm ${rootDir}/${projectType}/${language}/polywrap.${projectType}-${language}-linked*` + ); + } + }); + // run all commands for (const command of Object.keys(commands)) { test(`${command}`, async () => { diff --git a/packages/templates/wasm/rust/Cargo.toml b/packages/templates/wasm/rust/Cargo.toml index 62271d5b3e..a0fa2e31ad 100644 --- a/packages/templates/wasm/rust/Cargo.toml +++ b/packages/templates/wasm/rust/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT" edition = "2021" [dependencies] -polywrap-wasm-rs = { version = "0.1.0" } +polywrap-wasm-rs = { version = "0.10.0-pre.13" } serde = { version = "1.0", features = ["derive"] } [lib] diff --git a/packages/templates/wasm/rust/src/lib.rs b/packages/templates/wasm/rust/src/lib.rs index 670f68b50a..6503dc136b 100644 --- a/packages/templates/wasm/rust/src/lib.rs +++ b/packages/templates/wasm/rust/src/lib.rs @@ -1,9 +1,10 @@ pub mod wrap; pub use wrap::*; -pub fn sample_method(args: ArgsSampleMethod) -> SampleResult { - return SampleResult { - result: args.arg - }; +impl ModuleTrait for Module { + fn sample_method(args: ArgsSampleMethod) -> Result { + return Ok(SampleResult { + result: args.arg + }); + } } - diff --git a/packages/test-cases/cases/bind/sanity/output/wasm-rs/entry.rs b/packages/test-cases/cases/bind/sanity/output/wasm-rs/entry.rs index a5228d877e..9a410f9c8e 100644 --- a/packages/test-cases/cases/bind/sanity/output/wasm-rs/entry.rs +++ b/packages/test-cases/cases/bind/sanity/output/wasm-rs/entry.rs @@ -9,6 +9,7 @@ use polywrap_wasm_rs::{ invoke, InvokeArgs, }; +use crate::module::Module; #[no_mangle] pub extern "C" fn _wrap_invoke(method_size: u32, args_size: u32, env_size: u32) -> bool { @@ -16,12 +17,26 @@ pub extern "C" fn _wrap_invoke(method_size: u32, args_size: u32, env_size: u32) abort::wrap_abort_setup(); let args: InvokeArgs = invoke::wrap_invoke_args(method_size, args_size); + let result: Vec; match args.method.as_str() { - "moduleMethod" => invoke::wrap_invoke(args, env_size, Some(module_method_wrapped)), - "objectMethod" => invoke::wrap_invoke(args, env_size, Some(object_method_wrapped)), - "optionalEnvMethod" => invoke::wrap_invoke(args, env_size, Some(optional_env_method_wrapped)), - "if" => invoke::wrap_invoke(args, env_size, Some(if_wrapped)), - _ => invoke::wrap_invoke(args, env_size, None), - } + "moduleMethod" => { + result = module_method_wrapped(args.args.as_slice(), env_size); + } + "objectMethod" => { + result = object_method_wrapped(args.args.as_slice(), env_size); + } + "optionalEnvMethod" => { + result = optional_env_method_wrapped(args.args.as_slice(), env_size); + } + "if" => { + result = if_wrapped(args.args.as_slice(), env_size); + } + _ => { + invoke::wrap_invoke_error(format!("Could not find invoke function {}", args.method)); + return false; + } + }; + invoke::wrap_invoke_result(result); + return true; } diff --git a/packages/test-cases/cases/bind/sanity/output/wasm-rs/mod.rs b/packages/test-cases/cases/bind/sanity/output/wasm-rs/mod.rs index 325fb11fc3..d5a8b8e1e8 100644 --- a/packages/test-cases/cases/bind/sanity/output/wasm-rs/mod.rs +++ b/packages/test-cases/cases/bind/sanity/output/wasm-rs/mod.rs @@ -44,6 +44,8 @@ pub mod test_import; pub use test_import::TestImport; pub mod module; pub use module::{ + Module, + ModuleTrait, deserialize_module_method_args, serialize_module_method_result, module_method_wrapped, diff --git a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/mod.rs b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/mod.rs index 6ac60a9cea..7823ef5b88 100644 --- a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/mod.rs +++ b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/mod.rs @@ -20,3 +20,6 @@ pub use serialization::{ serialize_if_result, ArgsIf }; + +pub mod module; +pub use module::*; diff --git a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/module.rs b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/module.rs new file mode 100644 index 0000000000..f0fbdf1bcb --- /dev/null +++ b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/module.rs @@ -0,0 +1,31 @@ +use crate::{ + ArgsModuleMethod, + ArgsObjectMethod, + ArgsOptionalEnvMethod, + ArgsIf, +}; +use polywrap_wasm_rs::{ + BigInt, + BigNumber, + Map, + JSON, +}; + +use crate::Env; +use crate::{ + CustomEnum, +}; +use crate::AnotherType; +use crate::Else; + +pub struct Module; + +pub trait ModuleTrait { + fn module_method(args: ArgsModuleMethod) -> Result; + + fn object_method(args: ArgsObjectMethod, env: Env) -> Result, String>; + + fn optional_env_method(args: ArgsOptionalEnvMethod, env: Option) -> Result, String>; + + fn _if(args: ArgsIf) -> Result; +} diff --git a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/serialization.rs b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/serialization.rs index e11ac85bae..f4146f90b0 100644 --- a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/serialization.rs +++ b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/serialization.rs @@ -14,6 +14,7 @@ use polywrap_wasm_rs::{ JSON, }; +use crate::Env; use crate::{ CustomEnum, get_custom_enum_value, diff --git a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/wrapped.rs b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/wrapped.rs index 3703b2204b..e9316ed244 100644 --- a/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/wrapped.rs +++ b/packages/test-cases/cases/bind/sanity/output/wasm-rs/module/wrapped.rs @@ -3,30 +3,27 @@ use polywrap_wasm_rs::{ }; use crate::{ - module_method, ArgsModuleMethod, deserialize_module_method_args, serialize_module_method_result, - object_method, ArgsObjectMethod, deserialize_object_method_args, serialize_object_method_result, - optional_env_method, ArgsOptionalEnvMethod, deserialize_optional_env_method_args, serialize_optional_env_method_result, - _if, ArgsIf, deserialize_if_args, serialize_if_result }; +use crate::module::{ModuleTrait, Module}; use crate::Env; pub fn module_method_wrapped(args: &[u8], env_size: u32) -> Vec { match deserialize_module_method_args(args) { Ok(args) => { - let result = module_method(ArgsModuleMethod { + let result = Module::module_method(ArgsModuleMethod { str: args.str, opt_str: args.opt_str, en: args.en, @@ -39,7 +36,14 @@ pub fn module_method_wrapped(args: &[u8], env_size: u32) -> Vec { map_of_obj: args.map_of_obj, map_of_arr_of_obj: args.map_of_arr_of_obj, }); - serialize_module_method_result(&result).unwrap() + match result { + Ok(res) => { + serialize_module_method_result(&res).unwrap() + } + Err(e) => { + panic!("{}", e.to_string()) + } + } } Err(e) => { panic!("{}", e.to_string()) @@ -57,13 +61,20 @@ pub fn object_method_wrapped(args: &[u8], env_size: u32) -> Vec { match deserialize_object_method_args(args) { Ok(args) => { - let result = object_method(ArgsObjectMethod { + let result = Module::object_method(ArgsObjectMethod { object: args.object, opt_object: args.opt_object, object_array: args.object_array, opt_object_array: args.opt_object_array, }, env); - serialize_object_method_result(&result).unwrap() + match result { + Ok(res) => { + serialize_object_method_result(&res).unwrap() + } + Err(e) => { + panic!("{}", e.to_string()) + } + } } Err(e) => { panic!("{}", e.to_string()) @@ -73,7 +84,6 @@ pub fn object_method_wrapped(args: &[u8], env_size: u32) -> Vec { pub fn optional_env_method_wrapped(args: &[u8], env_size: u32) -> Vec { let mut env: Option = None; - if env_size > 0 { let env_buf = wrap_load_env(env_size); env = Some(Env::from_buffer(&env_buf).unwrap()); @@ -81,13 +91,20 @@ pub fn optional_env_method_wrapped(args: &[u8], env_size: u32) -> Vec { match deserialize_optional_env_method_args(args) { Ok(args) => { - let result = optional_env_method(ArgsOptionalEnvMethod { + let result = Module::optional_env_method(ArgsOptionalEnvMethod { object: args.object, opt_object: args.opt_object, object_array: args.object_array, opt_object_array: args.opt_object_array, }, env); - serialize_optional_env_method_result(&result).unwrap() + match result { + Ok(res) => { + serialize_optional_env_method_result(&res).unwrap() + } + Err(e) => { + panic!("{}", e.to_string()) + } + } } Err(e) => { panic!("{}", e.to_string()) @@ -98,10 +115,17 @@ pub fn optional_env_method_wrapped(args: &[u8], env_size: u32) -> Vec { pub fn if_wrapped(args: &[u8], env_size: u32) -> Vec { match deserialize_if_args(args) { Ok(args) => { - let result = _if(ArgsIf { + let result = Module::_if(ArgsIf { _if: args._if, }); - serialize_if_result(&result).unwrap() + match result { + Ok(res) => { + serialize_if_result(&res).unwrap() + } + Err(e) => { + panic!("{}", e.to_string()) + } + } } Err(e) => { panic!("{}", e.to_string()) diff --git a/packages/test-cases/cases/cli/wasm/build-cmd/rust/001-sanity/src/lib.rs b/packages/test-cases/cases/cli/wasm/build-cmd/rust/001-sanity/src/lib.rs index b46b844f2a..bab1bccc2b 100644 --- a/packages/test-cases/cases/cli/wasm/build-cmd/rust/001-sanity/src/lib.rs +++ b/packages/test-cases/cases/cli/wasm/build-cmd/rust/001-sanity/src/lib.rs @@ -1,6 +1,8 @@ pub mod wrap; pub use wrap::*; -pub fn method(args: wrap::module::ArgsMethod) -> String { - args.arg -} \ No newline at end of file +impl ModuleTrait for Module { + fn method(args: wrap::module::ArgsMethod) -> Result { + Ok(args.arg) + } +} diff --git a/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/polywrap.build.yaml b/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/polywrap.build.yaml index c506920d92..8e83cd434b 100644 --- a/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/polywrap.build.yaml +++ b/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/polywrap.build.yaml @@ -1,4 +1,7 @@ format: 0.2.0 strategies: image: - name: object-types-wasm-rs \ No newline at end of file + name: object-types-wasm-rs +linked_packages: + - name: "polywrap-wasm-rs" + path: ../../../../../../wasm/rs/ \ No newline at end of file diff --git a/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/src/lib.rs b/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/src/lib.rs index b46b844f2a..bab1bccc2b 100644 --- a/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/src/lib.rs +++ b/packages/test-cases/cases/cli/wasm/codegen/002-sanity-rust/src/lib.rs @@ -1,6 +1,8 @@ pub mod wrap; pub use wrap::*; -pub fn method(args: wrap::module::ArgsMethod) -> String { - args.arg -} \ No newline at end of file +impl ModuleTrait for Module { + fn method(args: wrap::module::ArgsMethod) -> Result { + Ok(args.arg) + } +} diff --git a/packages/wasm/rs/src/invoke.rs b/packages/wasm/rs/src/invoke.rs index c90d6d7348..ea76ad4a9f 100644 --- a/packages/wasm/rs/src/invoke.rs +++ b/packages/wasm/rs/src/invoke.rs @@ -57,3 +57,16 @@ pub fn wrap_invoke(args: InvokeArgs, env_size: u32, opt_invoke_func: Option) { + let res_len = result.len() as u32; + unsafe { __wrap_invoke_result(result.as_ptr() as u32, res_len) }; +} + +/// Helper for handling `wrap_invoke_error` +pub fn wrap_invoke_error(message: String) { + let msg_bytes = message.as_bytes(); + let msg_len = msg_bytes.len() as u32; + unsafe { __wrap_invoke_error(msg_bytes.as_ptr() as u32, msg_len) }; +} diff --git a/yarn.lock b/yarn.lock index 51eda99a3b..d2c9d476eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3536,9 +3536,9 @@ camelcase@^6.0.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001449: - version "1.0.30001475" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001475.tgz#1cf0a3003eddc6986f79b54c804981423ce127e3" - integrity sha512-6xvTuQbEjQvvdknKCA/B6w6edEG9OMrkTY3M2sre8Iau/5f9stnJA3RfnzUMZlVhcsp1Lyl2KsM8T2R8B3P0Kg== + version "1.0.30001477" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001477.tgz#a2ffb2276258233034bbb869d4558b02658a511e" + integrity sha512-lZim4iUHhGcy5p+Ri/G7m84hJwncj+Kz7S5aD4hoQfslKZJgt0tHc/hafVbqHC5bbhHb+mrW2JOUHkI5KH7toQ== capture-exit@^2.0.0: version "2.0.0" @@ -4357,9 +4357,9 @@ electron-fetch@^1.7.2: encoding "^0.1.13" electron-to-chromium@^1.4.284: - version "1.4.356" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.356.tgz#b75a8a8c31d571f6024310cc980a08cd6c15a8c5" - integrity sha512-nEftV1dRX3omlxAj42FwqRZT0i4xd2dIg39sog/CnCJeCcL1TRd2Uh0i9Oebgv8Ou0vzTPw++xc+Z20jzS2B6A== + version "1.4.357" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.357.tgz#ad02bab69e696e9a122788da4460c86166a98a01" + integrity sha512-UTkCbNTAcGXABmEnQrGcW4m3cG6fcyBfD4KDF0iyEAlbrGZiY9dmslyDAGOD1Kr5biN2F743Y30aRCOtau35Vw== elliptic@6.5.4: version "6.5.4" @@ -6039,9 +6039,9 @@ is-circular@^1.0.2: integrity sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA== is-core-module@^2.11.0, is-core-module@^2.5.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== + version "2.12.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" + integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== dependencies: has "^1.0.3" @@ -7535,9 +7535,9 @@ minimalistic-crypto-utils@^1.0.1: integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== minimatch@*: - version "8.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.3.tgz#0415cb9bb0c1d8ac758c8a673eb1d288e13f5e75" - integrity sha512-tEEvU9TkZgnFDCtpnrEYnPsjT7iUx42aXfs4bzmQ5sMA09/6hZY0jeZcGkXyDagiBOvkUjNo8Viom+Me6+2x7g== + version "9.0.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.0.tgz#bfc8e88a1c40ffd40c172ddac3decb8451503b56" + integrity sha512-0jJj8AvgKqWN05mrwuqi8QYKx1WmYSUoKSxu5Qhs9prezTz10sxAHGNZe9J9cqIJzta8DWsleh2KaVaLl6Ru2w== dependencies: brace-expansion "^2.0.1" @@ -7632,9 +7632,9 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: yallist "^4.0.0" minipass@^4.0.0: - version "4.2.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.5.tgz#9e0e5256f1e3513f8c34691dd68549e85b2c8ceb" - integrity sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q== + version "4.2.7" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.7.tgz#14c6fc0dcab54d9c4dd64b2b7032fef04efec218" + integrity sha512-ScVIgqHcXRMyfflqHmEW0bm8z8rb5McHyOY3ewX9JBgZaR77G7nxq9L/mtV96/QbAAwtbCAHVVLzD1kkyfFQEw== minizlib@^1.3.3: version "1.3.3" @@ -9308,13 +9308,20 @@ scrypt-js@3.0.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.3.8, semver@7.x, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: +semver@7.3.8: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== dependencies: lru-cache "^6.0.0" +semver@7.x, semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: + version "7.4.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.4.0.tgz#8481c92feffc531ab1e012a8ffc15bdd3a0f4318" + integrity sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw== + dependencies: + lru-cache "^6.0.0" + semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"