From 4954d865f16702b28f91dd25dd4c9eec98af17cc Mon Sep 17 00:00:00 2001 From: Jonas Kruckenberg Date: Sun, 10 Sep 2023 14:29:14 +0200 Subject: [PATCH] feat(rust): implement resource --- crates/core/src/lib.rs | 5 +- crates/gen-guest-js/src/lib.rs | 17 +- crates/gen-guest-rust/src/lib.rs | 33 +- crates/gen-guest-rust/tests/resources.rs | 34 +- crates/gen-guest-ts/src/lib.rs | 17 +- crates/gen-guest-ts/tests/variants.ts | 1099 +++++++++++----------- crates/gen-host/src/lib.rs | 18 +- crates/gen-rust/src/lib.rs | 3 +- 8 files changed, 654 insertions(+), 572 deletions(-) diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index ca15c75..461dded 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -73,7 +73,10 @@ pub struct TypeInfos { impl TypeInfos { #[must_use] - pub fn collect_from_functions(typedefs: &TypeDefArena, functions: &[Function]) -> Self { + pub fn collect_from_functions<'a>( + typedefs: &TypeDefArena, + functions: impl Iterator, + ) -> Self { let mut this = Self::default(); for func in functions { diff --git a/crates/gen-guest-js/src/lib.rs b/crates/gen-guest-js/src/lib.rs index 1be9c4b..7f16a9a 100644 --- a/crates/gen-guest-js/src/lib.rs +++ b/crates/gen-guest-js/src/lib.rs @@ -23,7 +23,22 @@ pub struct Builder { impl GeneratorBuilder for Builder { fn build(self, interface: Interface) -> Box { - let infos = TypeInfos::collect_from_functions(&interface.typedefs, &interface.functions); + let methods = interface + .typedefs + .iter() + .filter_map(|(_, typedef)| { + if let TypeDefKind::Resource(methods) = &typedef.kind { + Some(methods.iter()) + } else { + None + } + }) + .flatten(); + + let infos = TypeInfos::collect_from_functions( + &interface.typedefs, + interface.functions.iter().chain(methods), + ); let serde_utils = SerdeUtils::collect_from_functions(&interface.typedefs, &interface.functions); diff --git a/crates/gen-guest-rust/src/lib.rs b/crates/gen-guest-rust/src/lib.rs index b3fdc8a..4c59b66 100644 --- a/crates/gen-guest-rust/src/lib.rs +++ b/crates/gen-guest-rust/src/lib.rs @@ -14,6 +14,7 @@ use tauri_bindgen_core::TypeInfo; use tauri_bindgen_core::TypeInfos; use tauri_bindgen_gen_rust::FnSig; use tauri_bindgen_gen_rust::{BorrowMode, RustGenerator}; +use wit_parser::TypeDefKind; use wit_parser::{Function, Interface}; #[derive(Default, Debug, Clone)] @@ -35,7 +36,22 @@ pub struct Builder { impl GeneratorBuilder for Builder { fn build(self, interface: Interface) -> Box { - let infos = TypeInfos::collect_from_functions(&interface.typedefs, &interface.functions); + let methods = interface + .typedefs + .iter() + .filter_map(|(_, typedef)| { + if let TypeDefKind::Resource(methods) = &typedef.kind { + Some(methods.iter()) + } else { + None + } + }) + .flatten(); + + let infos = TypeInfos::collect_from_functions( + &interface.typedefs, + interface.functions.iter().chain(methods), + ); Box::new(RustWasm { opts: self, @@ -117,6 +133,7 @@ impl RustGenerator for RustWasm { fn print_resource( &self, + mod_ident: &str, docs: &str, ident: &proc_macro2::Ident, functions: &[Function], @@ -139,9 +156,17 @@ impl RustGenerator for RustWasm { &BorrowMode::Owned, ); + let mod_ident = format!("{mod_ident}::resource::{}", ident.to_string().to_snake_case()); + let ident = func.ident.to_snake_case(); + + let param_idents = func + .params + .iter() + .map(|(ident, _)| format_ident!("{}", ident)); + quote! { #sig { - todo!() + ::tauri_bindgen_guest_rust::invoke(#mod_ident, #ident, &(self.0, #(#param_idents),*)).await.unwrap() } } }); @@ -149,9 +174,7 @@ impl RustGenerator for RustWasm { quote! { #docs #additional_attrs - pub struct #ident { - id: u64 - } + pub struct #ident(u32); impl #ident { #(#functions)* diff --git a/crates/gen-guest-rust/tests/resources.rs b/crates/gen-guest-rust/tests/resources.rs index e486d62..fcd2c05 100644 --- a/crates/gen-guest-rust/tests/resources.rs +++ b/crates/gen-guest-rust/tests/resources.rs @@ -3,34 +3,42 @@ pub mod resources { use ::tauri_bindgen_guest_rust::serde; use ::tauri_bindgen_guest_rust::bitflags; - #[derive(serde::Deserialize)] - pub struct A { - id: u64, - } + #[derive(serde::Serialize, serde::Deserialize)] + pub struct A(u32); impl A { pub async fn f1(&self) { - todo!() + ::tauri_bindgen_guest_rust::invoke("resources;::resource::A", "f1", &()) + .await + .unwrap() } pub async fn f2(&self, a: u32) { - todo!() + ::tauri_bindgen_guest_rust::invoke("resources;::resource::A", "f2", &(a)) + .await + .unwrap() } pub async fn f3(&self, a: u32, b: u32) { - todo!() + ::tauri_bindgen_guest_rust::invoke("resources;::resource::A", "f3", &(a, b)) + .await + .unwrap() } } #[derive(serde::Deserialize)] - pub struct B { - id: u64, - } + pub struct B(u32); impl B { pub async fn f1(&self) -> A { - todo!() + ::tauri_bindgen_guest_rust::invoke("resources;::resource::B", "f1", &()) + .await + .unwrap() } pub async fn f2(&self, x: A) -> Result { - todo!() + ::tauri_bindgen_guest_rust::invoke("resources;::resource::B", "f2", &(x)) + .await + .unwrap() } pub async fn f3(&self, x: Option<&'_ [A]>) -> Result { - todo!() + ::tauri_bindgen_guest_rust::invoke("resources;::resource::B", "f3", &(x)) + .await + .unwrap() } } pub async fn constructor_a() -> A { diff --git a/crates/gen-guest-ts/src/lib.rs b/crates/gen-guest-ts/src/lib.rs index d50cb84..d5fbd2f 100644 --- a/crates/gen-guest-ts/src/lib.rs +++ b/crates/gen-guest-ts/src/lib.rs @@ -31,7 +31,22 @@ pub struct Builder { impl GeneratorBuilder for Builder { fn build(self, interface: Interface) -> Box { - let infos = TypeInfos::collect_from_functions(&interface.typedefs, &interface.functions); + let methods = interface + .typedefs + .iter() + .filter_map(|(_, typedef)| { + if let TypeDefKind::Resource(methods) = &typedef.kind { + Some(methods.iter()) + } else { + None + } + }) + .flatten(); + + let infos = TypeInfos::collect_from_functions( + &interface.typedefs, + interface.functions.iter().chain(methods), + ); let serde_utils = SerdeUtils::collect_from_functions(&interface.typedefs, &interface.functions); diff --git a/crates/gen-guest-ts/tests/variants.ts b/crates/gen-guest-ts/tests/variants.ts index 06f5051..08e590b 100644 --- a/crates/gen-guest-ts/tests/variants.ts +++ b/crates/gen-guest-ts/tests/variants.ts @@ -1,23 +1,23 @@ // @ts-nocheck export type Result = { tag: 'ok', val: T } | { tag: 'err', val: E }; class Deserializer { - source - offset + source + offset + + constructor(bytes) { + this.source = bytes + this.offset = 0 + } - constructor(bytes) { - this.source = bytes - this.offset = 0 - } + pop() { + return this.source[this.offset++] + } - pop() { - return this.source[this.offset++] - } - - try_take_n(len) { - const out = this.source.slice(this.offset, this.offset + len) - this.offset += len - return out - } + try_take_n(len) { + const out = this.source.slice(this.offset, this.offset + len) + this.offset += len + return out + } } // function varint_max(bits) { // const BITS_PER_BYTE = 8; @@ -79,31 +79,31 @@ function de_varint_big(de, bits) { throw new Error('deserialize bad variant') } function deserializeBool(de) { - const val = de.pop(); + const val = de.pop(); - return val != 0 + return val != 0 } function deserializeU8(de) { - return de.pop() + return de.pop() } function deserializeU32(de) { - return de_varint(de, 32) + return de_varint(de, 32) } function deserializeU64(de) { return de_varint_big(de, 64) } function deserializeS8(de) { - const buf = new ArrayBuffer(1); - const view = new DataView(buf); + const buf = new ArrayBuffer(1); + const view = new DataView(buf); - buf[0] = view.setUint8(0, de.pop()); + buf[0] = view.setUint8(0, de.pop()); - return view.getInt8(0); + return view.getInt8(0); } function deserializeS32(de) { - const n = de_varint(de, 32) + const n = de_varint(de, 32) - return Number(((n >> 1) & 0xFFFFFFFF) ^ (-((n & 0b1) & 0xFFFFFFFF))) + return Number(((n >> 1) & 0xFFFFFFFF) ^ (-((n & 0b1) & 0xFFFFFFFF))) } function deserializeS64(de) { const n = de_varint_big(de, 64) @@ -111,62 +111,62 @@ function deserializeS64(de) { return ((n >> 1n) & 0xFFFFFFFFFFFFFFFFn) ^ (-((n & 0b1n) & 0xFFFFFFFFFFFFFFFFn)) } function deserializeF32(de) { - const bytes = de.try_take_n(4); + const bytes = de.try_take_n(4); - const buf = new ArrayBuffer(4); - const view = new DataView(buf); + const buf = new ArrayBuffer(4); + const view = new DataView(buf); - bytes.forEach((v, i) => view.setUint8(i, v)); + bytes.forEach((v, i) => view.setUint8(i, v)); - return view.getFloat32(0, true); + return view.getFloat32(0, true); } function deserializeF64(de) { - const bytes = de.try_take_n(8); + const bytes = de.try_take_n(8); - const buf = new ArrayBuffer(8); - const view = new DataView(buf); + const buf = new ArrayBuffer(8); + const view = new DataView(buf); - bytes.forEach((v, i) => view.setUint8(i, v)); + bytes.forEach((v, i) => view.setUint8(i, v)); - return view.getFloat64(0, true); + return view.getFloat64(0, true); } function deserializeString(de) { - const sz = deserializeU64(de); + const sz = deserializeU64(de); - let bytes = de.try_take_n(Number(sz)); + let bytes = de.try_take_n(Number(sz)); - return __text_decoder.decode(bytes); + return __text_decoder.decode(bytes); } function deserializeBytes(de) { - const sz = deserializeU64(de); + const sz = deserializeU64(de); - let bytes = de.try_take_n(Number(sz)); + let bytes = de.try_take_n(Number(sz)); - return bytes; + return bytes; } function deserializeOption(de, inner) { - const tag = de.pop() + const tag = de.pop() - switch (tag) { - case 0: - return null - case 1: - return inner(de) - default: - throw new Error(`Deserialize bad option ${tag}`) - } + switch (tag) { + case 0: + return null + case 1: + return inner(de) + default: + throw new Error(`Deserialize bad option ${tag}`) + } } function deserializeResult(de, ok, err) { - const tag = de.pop() + const tag = de.pop() - switch (tag) { - case 0: - return { tag: 'ok', val: ok(de) } - case 1: - return { tag: 'err', val: err(de) } - default: - throw new Error(`Deserialize bad result ${tag}`) - } + switch (tag) { + case 0: + return { tag: 'ok', val: ok(de) } + case 1: + return { tag: 'err', val: err(de) } + default: + throw new Error(`Deserialize bad result ${tag}`) + } } function ser_varint(out, bits, val) { let buf = [] @@ -204,370 +204,370 @@ function ser_varint_big(out, bits, val) { out.push(...buf) } function serializeBool(out, val) { - out.push(val === true ? 1 : 0) + out.push(val === true ? 1 : 0) } function serializeU8(out, val) { - return out.push(val) + return out.push(val) } function serializeU32(out, val) { - return ser_varint(out, 32, val) + return ser_varint(out, 32, val) } function serializeU64(out, val) { return ser_varint_big(out, 64, BigInt(val)) } function serializeS8(out, val) { - out.push(val) + out.push(val) } function serializeS32(out, val) { - ser_varint(out, 32, (val << 1) ^ (val >> 31)) + ser_varint(out, 32, (val << 1) ^ (val >> 31)) } function serializeS64(out, val) { val = BigInt(val) ser_varint_big(out, 64, (val << 1n) ^ (val >> 63n)) } function serializeF32(out, val) { - const buf = new ArrayBuffer(4); - const view = new DataView(buf); + const buf = new ArrayBuffer(4); + const view = new DataView(buf); - view.setFloat32(0, val, true); + view.setFloat32(0, val, true); - out.push(...new Uint8Array(buf)) + out.push(...new Uint8Array(buf)) } function serializeF64(out, val) { - const buf = new ArrayBuffer(8); - const view = new DataView(buf); + const buf = new ArrayBuffer(8); + const view = new DataView(buf); - view.setFloat64(0, val, true); + view.setFloat64(0, val, true); - out.push(...new Uint8Array(buf)) + out.push(...new Uint8Array(buf)) } function serializeString(out, val) { - serializeU64(out, val.length); + serializeU64(out, val.length); - out.push(...__text_encoder.encode(val)) + out.push(...__text_encoder.encode(val)) } function serializeBytes(out, val) { - serializeU64(out, val.length); - out.push(...val) + serializeU64(out, val.length); + out.push(...val) } function serializeOption(out, inner, val) { - serializeU8(out, !!val ? 1 : 0) - if (val) { - inner(out, val) - } + serializeU8(out, !!val ? 1 : 0) + if (val) { + inner(out, val) + } } function serializeResult(out, ok, err, val) { - if (val.Ok) { - serializeU8(out, 0); - return ok(out, val.Ok); - } + if (val.Ok) { + serializeU8(out, 0); + return ok(out, val.Ok); + } - if (val.Err) { - serializeU8(out, 1); - return err(out, val.Err); - } + if (val.Err) { + serializeU8(out, 1); + return err(out, val.Err); + } - throw new Error(`Serialize bad result ${val}`); + throw new Error(`Serialize bad result ${val}`); } const __text_decoder = new TextDecoder('utf-8'); const __text_encoder = new TextEncoder(); function deserializeE1(de) { - const tag = deserializeU32(de) + const tag = deserializeU32(de) - switch (tag) { - case 0: - return "A" + switch (tag) { + case 0: + return "A" - default: - throw new Error(`unknown enum case ${tag}`) - } -} function deserializeU1(de) { - const tag = deserializeU32(de) + default: + throw new Error(`unknown enum case ${tag}`) + } +}function deserializeU1(de) { + const tag = deserializeU32(de) - switch (tag) { - case 0: - return { U32: deserializeU32(de) } - case 1: - return { F32: deserializeF32(de) } + switch (tag) { + case 0: + return { U32: deserializeU32(de) } +case 1: + return { F32: deserializeF32(de) } - default: - throw new Error(`unknown union case ${tag}`) - } -} function deserializeEmpty(de) { - return { + default: + throw new Error(`unknown union case ${tag}`) + } +}function deserializeEmpty(de) { + return { + + } +}function deserializeV1(de) { + const tag = deserializeU32(de) - } -} function deserializeV1(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: null } +case 1: + return { B: deserializeU1(de) } +case 2: + return { C: deserializeE1(de) } +case 3: + return { D: deserializeString(de) } +case 4: + return { E: deserializeEmpty(de) } +case 5: + return { F: null } +case 6: + return { G: deserializeU32(de) } - switch (tag) { - case 0: - return { A: null } - case 1: - return { B: deserializeU1(de) } - case 2: - return { C: deserializeE1(de) } - case 3: - return { D: deserializeString(de) } - case 4: - return { E: deserializeEmpty(de) } - case 5: - return { F: null } - case 6: - return { G: deserializeU32(de) } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeCasts1(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeCasts1(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: deserializeS32(de) } +case 1: + return { B: deserializeF32(de) } - switch (tag) { - case 0: - return { A: deserializeS32(de) } - case 1: - return { B: deserializeF32(de) } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeCasts2(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeCasts2(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: deserializeF64(de) } +case 1: + return { B: deserializeF32(de) } - switch (tag) { - case 0: - return { A: deserializeF64(de) } - case 1: - return { B: deserializeF32(de) } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeCasts3(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeCasts3(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: deserializeF64(de) } +case 1: + return { B: deserializeU64(de) } - switch (tag) { - case 0: - return { A: deserializeF64(de) } - case 1: - return { B: deserializeU64(de) } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeCasts4(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeCasts4(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: deserializeU32(de) } +case 1: + return { B: deserializeS64(de) } - switch (tag) { - case 0: - return { A: deserializeU32(de) } - case 1: - return { B: deserializeS64(de) } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeCasts5(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeCasts5(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: deserializeF32(de) } +case 1: + return { B: deserializeS64(de) } - switch (tag) { - case 0: - return { A: deserializeF32(de) } - case 1: - return { B: deserializeS64(de) } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeCasts6(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeCasts6(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return { A: [deserializeF32(de), deserializeU32(de)] } +case 1: + return { B: [deserializeU32(de), deserializeU32(de)] } - switch (tag) { - case 0: - return { A: [deserializeF32(de), deserializeU32(de)] } - case 1: - return { B: [deserializeU32(de), deserializeU32(de)] } + default: + throw new Error(`unknown variant case ${tag}`) + } +}function deserializeMyErrno(de) { + const tag = deserializeU32(de) - default: - throw new Error(`unknown variant case ${tag}`) - } -} function deserializeMyErrno(de) { - const tag = deserializeU32(de) + switch (tag) { + case 0: + return "Bad1" +case 1: + return "Bad2" - switch (tag) { - case 0: - return "Bad1" - case 1: - return "Bad2" + default: + throw new Error(`unknown enum case ${tag}`) + } +}function deserializeIsClone(de) { + return { + v1: deserializeV1(de) + } +}function serializeE1(out, val) { + switch (val) { + case "A": + serializeU32(out, 0) + return - default: - throw new Error(`unknown enum case ${tag}`) - } -} function deserializeIsClone(de) { - return { - v1: deserializeV1(de) - } -} function serializeE1(out, val) { - switch (val) { - case "A": - serializeU32(out, 0) - return - - default: - throw new Error("unknown enum case") - } -} function serializeU1(out, val) { - if (val.U32) { + default: + throw new Error("unknown enum case") + } +}function serializeU1(out, val) { + if (val.U32) { serializeU32(out, 0); return serializeU32(out, val.U32) - } - if (val.F32) { +} + if (val.F32) { serializeU32(out, 1); return serializeF32(out, val.F32) - } +} + - - throw new Error("unknown union case") -} function serializeEmpty(out, val) { - -} function serializeV1(out, val) { - if (val.A) { + throw new Error("unknown union case") +}function serializeEmpty(out, val) { + +}function serializeV1(out, val) { + if (val.A) { serializeU32(out, 0); - + return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); serializeU1(out, val.B) return - } - if (val.C) { +} +if (val.C) { serializeU32(out, 2); serializeE1(out, val.C) return - } - if (val.D) { +} +if (val.D) { serializeU32(out, 3); serializeString(out, val.D) return - } - if (val.E) { +} +if (val.E) { serializeU32(out, 4); serializeEmpty(out, val.E) return - } - if (val.F) { +} +if (val.F) { serializeU32(out, 5); - + return - } - if (val.G) { +} +if (val.G) { serializeU32(out, 6); serializeU32(out, val.G) return - } +} - throw new Error("unknown variant case") -} function serializeCasts1(out, val) { - if (val.A) { + throw new Error("unknown variant case") +}function serializeCasts1(out, val) { + if (val.A) { serializeU32(out, 0); serializeS32(out, val.A) return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); serializeF32(out, val.B) return - } +} - throw new Error("unknown variant case") -} function serializeCasts2(out, val) { - if (val.A) { + throw new Error("unknown variant case") +}function serializeCasts2(out, val) { + if (val.A) { serializeU32(out, 0); serializeF64(out, val.A) return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); serializeF32(out, val.B) return - } +} - throw new Error("unknown variant case") -} function serializeCasts3(out, val) { - if (val.A) { + throw new Error("unknown variant case") +}function serializeCasts3(out, val) { + if (val.A) { serializeU32(out, 0); serializeF64(out, val.A) return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); serializeU64(out, val.B) return - } +} - throw new Error("unknown variant case") -} function serializeCasts4(out, val) { - if (val.A) { + throw new Error("unknown variant case") +}function serializeCasts4(out, val) { + if (val.A) { serializeU32(out, 0); serializeU32(out, val.A) return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); serializeS64(out, val.B) return - } +} - throw new Error("unknown variant case") -} function serializeCasts5(out, val) { - if (val.A) { + throw new Error("unknown variant case") +}function serializeCasts5(out, val) { + if (val.A) { serializeU32(out, 0); serializeF32(out, val.A) return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); serializeS64(out, val.B) return - } +} - throw new Error("unknown variant case") -} function serializeCasts6(out, val) { - if (val.A) { + throw new Error("unknown variant case") +}function serializeCasts6(out, val) { + if (val.A) { serializeU32(out, 0); - { serializeF32(out, val.A[0]); serializeU32(out, val.A[1]) } + {serializeF32(out, val.A[0]);serializeU32(out, val.A[1])} return - } - if (val.B) { +} +if (val.B) { serializeU32(out, 1); - { serializeU32(out, val.B[0]); serializeU32(out, val.B[1]) } + {serializeU32(out, val.B[0]);serializeU32(out, val.B[1])} return - } - - - throw new Error("unknown variant case") -} function serializeIsClone(out, val) { - serializeV1(out, val.v1) } -export enum E1 { - A, + + throw new Error("unknown variant case") +}function serializeIsClone(out, val) { + serializeV1(out, val.v1) } -export type U1 = - number - | - number - ; +export enum E1 { +A, + } -export interface Empty { } +export type U1 = +number + | +number +; + +export interface Empty { } export interface V1A { tag: 0 } @@ -584,386 +584,387 @@ export interface V1F { tag: 5 } export interface V1G { tag: 6, value: number } -export type V1 = - V1A | - V1B | - V1C | - V1D | - V1E | - V1F | - V1G +export type V1 = +V1A | +V1B | +V1C | +V1D | +V1E | +V1F | +V1G export interface Casts1A { tag: 0, value: number } export interface Casts1B { tag: 1, value: number } -export type Casts1 = - Casts1A | - Casts1B +export type Casts1 = +Casts1A | +Casts1B export interface Casts2A { tag: 0, value: number } export interface Casts2B { tag: 1, value: number } -export type Casts2 = - Casts2A | - Casts2B +export type Casts2 = +Casts2A | +Casts2B export interface Casts3A { tag: 0, value: number } export interface Casts3B { tag: 1, value: bigint } -export type Casts3 = - Casts3A | - Casts3B +export type Casts3 = +Casts3A | +Casts3B export interface Casts4A { tag: 0, value: number } export interface Casts4B { tag: 1, value: bigint } -export type Casts4 = - Casts4A | - Casts4B +export type Casts4 = +Casts4A | +Casts4B export interface Casts5A { tag: 0, value: number } export interface Casts5B { tag: 1, value: bigint } -export type Casts5 = - Casts5A | - Casts5B +export type Casts5 = +Casts5A | +Casts5B export interface Casts6A { tag: 0, value: [number, number] } export interface Casts6B { tag: 1, value: [number, number] } -export type Casts6 = - Casts6A | - Casts6B +export type Casts6 = +Casts6A | +Casts6B -export enum MyErrno { - Bad1, +export enum MyErrno { +Bad1, - Bad2, +Bad2, + } + +export interface IsClone { +v1: V1, + } + + + +export async function e1Arg (x: E1) : Promise { + const out = [] + serializeE1(out, x) + + fetch('ipc://localhost/variants/e1_arg', { method: "POST", body: Uint8Array.from(out) }) } + -export interface IsClone { - v1: V1, +export async function e1Result () : Promise { + const out = [] + + + return fetch('ipc://localhost/variants/e1_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) + + return deserializeE1(de) + }) as Promise } + +export async function u1Arg (x: U1) : Promise { + const out = [] + serializeU1(out, x) - -export async function e1Arg(x: E1): Promise { - const out = [] - serializeE1(out, x) - - fetch('ipc://localhost/variants/e1_arg', { method: "POST", body: Uint8Array.from(out) }) + fetch('ipc://localhost/variants/u1_arg', { method: "POST", body: Uint8Array.from(out) }) } + +export async function u1Result () : Promise { + const out = [] + -export async function e1Result(): Promise { - const out = [] + return fetch('ipc://localhost/variants/u1_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/e1_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeE1(de) - }) as Promise + return deserializeU1(de) + }) as Promise } + +export async function v1Arg (x: V1) : Promise { + const out = [] + serializeV1(out, x) -export async function u1Arg(x: U1): Promise { - const out = [] - serializeU1(out, x) - - fetch('ipc://localhost/variants/u1_arg', { method: "POST", body: Uint8Array.from(out) }) + fetch('ipc://localhost/variants/v1_arg', { method: "POST", body: Uint8Array.from(out) }) } + +export async function v1Result () : Promise { + const out = [] + -export async function u1Result(): Promise { - const out = [] + return fetch('ipc://localhost/variants/v1_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/u1_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeU1(de) - }) as Promise + return deserializeV1(de) + }) as Promise } + +export async function boolArg (x: boolean) : Promise { + const out = [] + serializeBool(out, x) -export async function v1Arg(x: V1): Promise { - const out = [] - serializeV1(out, x) - - fetch('ipc://localhost/variants/v1_arg', { method: "POST", body: Uint8Array.from(out) }) + fetch('ipc://localhost/variants/bool_arg', { method: "POST", body: Uint8Array.from(out) }) } + +export async function boolResult () : Promise { + const out = [] + -export async function v1Result(): Promise { - const out = [] + return fetch('ipc://localhost/variants/bool_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/v1_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeV1(de) - }) as Promise + return deserializeBool(de) + }) as Promise } + +export async function optionArg (a: boolean | null, b: [] | null, c: number | null, d: E1 | null, e: number | null, f: U1 | null, g: boolean | null | null) : Promise { + const out = [] + serializeOption(out, (out, v) => serializeBool(out, v), a); +serializeOption(out, (out, v) => {}, b); +serializeOption(out, (out, v) => serializeU32(out, v), c); +serializeOption(out, (out, v) => serializeE1(out, v), d); +serializeOption(out, (out, v) => serializeF32(out, v), e); +serializeOption(out, (out, v) => serializeU1(out, v), f); +serializeOption(out, (out, v) => serializeOption(out, (out, v) => serializeBool(out, v), v), g) -export async function boolArg(x: boolean): Promise { - const out = [] - serializeBool(out, x) - - fetch('ipc://localhost/variants/bool_arg', { method: "POST", body: Uint8Array.from(out) }) + fetch('ipc://localhost/variants/option_arg', { method: "POST", body: Uint8Array.from(out) }) } + +export async function optionResult () : Promise<[boolean | null, [] | null, number | null, E1 | null, number | null, U1 | null, boolean | null | null]> { + const out = [] + -export async function boolResult(): Promise { - const out = [] + return fetch('ipc://localhost/variants/option_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/bool_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeBool(de) - }) as Promise + return [deserializeOption(de, (de) => deserializeBool(de)), deserializeOption(de, (de) => []), deserializeOption(de, (de) => deserializeU32(de)), deserializeOption(de, (de) => deserializeE1(de)), deserializeOption(de, (de) => deserializeF32(de)), deserializeOption(de, (de) => deserializeU1(de)), deserializeOption(de, (de) => deserializeOption(de, (de) => deserializeBool(de)))] + }) as Promise<[boolean | null, [] | null, number | null, E1 | null, number | null, U1 | null, boolean | null | null]> } + +export async function casts (a: Casts1, b: Casts2, c: Casts3, d: Casts4, e: Casts5, f: Casts6) : Promise<[Casts1, Casts2, Casts3, Casts4, Casts5, Casts6]> { + const out = [] + serializeCasts1(out, a); +serializeCasts2(out, b); +serializeCasts3(out, c); +serializeCasts4(out, d); +serializeCasts5(out, e); +serializeCasts6(out, f) -export async function optionArg(a: boolean | null, b: [] | null, c: number | null, d: E1 | null, e: number | null, f: U1 | null, g: boolean | null | null): Promise { - const out = [] - serializeOption(out, (out, v) => serializeBool(out, v), a); - serializeOption(out, (out, v) => { }, b); - serializeOption(out, (out, v) => serializeU32(out, v), c); - serializeOption(out, (out, v) => serializeE1(out, v), d); - serializeOption(out, (out, v) => serializeF32(out, v), e); - serializeOption(out, (out, v) => serializeU1(out, v), f); - serializeOption(out, (out, v) => serializeOption(out, (out, v) => serializeBool(out, v), v), g) + return fetch('ipc://localhost/variants/casts', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - fetch('ipc://localhost/variants/option_arg', { method: "POST", body: Uint8Array.from(out) }) + return [deserializeCasts1(de), deserializeCasts2(de), deserializeCasts3(de), deserializeCasts4(de), deserializeCasts5(de), deserializeCasts6(de)] + }) as Promise<[Casts1, Casts2, Casts3, Casts4, Casts5, Casts6]> } + +export async function resultArg (a: Result, b: Result, c: Result, d: Result<[], []>, e: Result, f: Result) : Promise { + const out = [] + serializeResult(out, (out, v) => {}, (out, v) => {}, a); +serializeResult(out, (out, v) => {}, (out, v) => serializeE1(out, v), b); +serializeResult(out, (out, v) => serializeE1(out, v), (out, v) => {}, c); +serializeResult(out, (out, v) => {}, (out, v) => {}, d); +serializeResult(out, (out, v) => serializeU32(out, v), (out, v) => serializeV1(out, v), e); +serializeResult(out, (out, v) => serializeString(out, v), (out, v) => serializeBytes(out, v), f) -export async function optionResult(): Promise<[boolean | null, [] | null, number | null, E1 | null, number | null, U1 | null, boolean | null | null]> { - const out = [] - - - return fetch('ipc://localhost/variants/option_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return [deserializeOption(de, (de) => deserializeBool(de)), deserializeOption(de, (de) => []), deserializeOption(de, (de) => deserializeU32(de)), deserializeOption(de, (de) => deserializeE1(de)), deserializeOption(de, (de) => deserializeF32(de)), deserializeOption(de, (de) => deserializeU1(de)), deserializeOption(de, (de) => deserializeOption(de, (de) => deserializeBool(de)))] - }) as Promise<[boolean | null, [] | null, number | null, E1 | null, number | null, U1 | null, boolean | null | null]> + fetch('ipc://localhost/variants/result_arg', { method: "POST", body: Uint8Array.from(out) }) } + +export async function resultResult () : Promise<[Result, Result, Result, Result<[], []>, Result, Result]> { + const out = [] + -export async function casts(a: Casts1, b: Casts2, c: Casts3, d: Casts4, e: Casts5, f: Casts6): Promise<[Casts1, Casts2, Casts3, Casts4, Casts5, Casts6]> { - const out = [] - serializeCasts1(out, a); - serializeCasts2(out, b); - serializeCasts3(out, c); - serializeCasts4(out, d); - serializeCasts5(out, e); - serializeCasts6(out, f) + return fetch('ipc://localhost/variants/result_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - return fetch('ipc://localhost/variants/casts', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return [deserializeCasts1(de), deserializeCasts2(de), deserializeCasts3(de), deserializeCasts4(de), deserializeCasts5(de), deserializeCasts6(de)] - }) as Promise<[Casts1, Casts2, Casts3, Casts4, Casts5, Casts6]> + return [deserializeResult(de, () => {}, () => {}), deserializeResult(de, () => {}, (de) => deserializeE1(de)), deserializeResult(de, (de) => deserializeE1(de), () => {}), deserializeResult(de, (de) => [], (de) => []), deserializeResult(de, (de) => deserializeU32(de), (de) => deserializeV1(de)), deserializeResult(de, (de) => deserializeString(de), (de) => deserializeBytes(de))] + }) as Promise<[Result, Result, Result, Result<[], []>, Result, Result]> } + +export async function returnResultSugar () : Promise> { + const out = [] + -export async function resultArg(a: Result, b: Result, c: Result, d: Result<[], []>, e: Result, f: Result): Promise { - const out = [] - serializeResult(out, (out, v) => { }, (out, v) => { }, a); - serializeResult(out, (out, v) => { }, (out, v) => serializeE1(out, v), b); - serializeResult(out, (out, v) => serializeE1(out, v), (out, v) => { }, c); - serializeResult(out, (out, v) => { }, (out, v) => { }, d); - serializeResult(out, (out, v) => serializeU32(out, v), (out, v) => serializeV1(out, v), e); - serializeResult(out, (out, v) => serializeString(out, v), (out, v) => serializeBytes(out, v), f) + return fetch('ipc://localhost/variants/return_result_sugar', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - fetch('ipc://localhost/variants/result_arg', { method: "POST", body: Uint8Array.from(out) }) + return deserializeResult(de, (de) => deserializeS32(de), (de) => deserializeMyErrno(de)) + }) as Promise> } + +export async function returnResultSugar2 () : Promise> { + const out = [] + -export async function resultResult(): Promise<[Result, Result, Result, Result<[], []>, Result, Result]> { - const out = [] + return fetch('ipc://localhost/variants/return_result_sugar2', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/result_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return [deserializeResult(de, () => { }, () => { }), deserializeResult(de, () => { }, (de) => deserializeE1(de)), deserializeResult(de, (de) => deserializeE1(de), () => { }), deserializeResult(de, (de) => [], (de) => []), deserializeResult(de, (de) => deserializeU32(de), (de) => deserializeV1(de)), deserializeResult(de, (de) => deserializeString(de), (de) => deserializeBytes(de))] - }) as Promise<[Result, Result, Result, Result<[], []>, Result, Result]> + return deserializeResult(de, () => {}, (de) => deserializeMyErrno(de)) + }) as Promise> } + +export async function returnResultSugar3 () : Promise> { + const out = [] + -export async function returnResultSugar(): Promise> { - const out = [] + return fetch('ipc://localhost/variants/return_result_sugar3', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/return_result_sugar', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeResult(de, (de) => deserializeS32(de), (de) => deserializeMyErrno(de)) - }) as Promise> + return deserializeResult(de, (de) => deserializeMyErrno(de), (de) => deserializeMyErrno(de)) + }) as Promise> } + +export async function returnResultSugar4 () : Promise> { + const out = [] + -export async function returnResultSugar2(): Promise> { - const out = [] + return fetch('ipc://localhost/variants/return_result_sugar4', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/return_result_sugar2', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeResult(de, () => { }, (de) => deserializeMyErrno(de)) - }) as Promise> + return deserializeResult(de, (de) => [deserializeS32(de), deserializeU32(de)], (de) => deserializeMyErrno(de)) + }) as Promise> } + +export async function returnOptionSugar () : Promise { + const out = [] + -export async function returnResultSugar3(): Promise> { - const out = [] + return fetch('ipc://localhost/variants/return_option_sugar', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/return_result_sugar3', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeResult(de, (de) => deserializeMyErrno(de), (de) => deserializeMyErrno(de)) - }) as Promise> + return deserializeOption(de, (de) => deserializeS32(de)) + }) as Promise } + +export async function returnOptionSugar2 () : Promise { + const out = [] + -export async function returnResultSugar4(): Promise> { - const out = [] + return fetch('ipc://localhost/variants/return_option_sugar2', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/return_result_sugar4', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeResult(de, (de) => [deserializeS32(de), deserializeU32(de)], (de) => deserializeMyErrno(de)) - }) as Promise> + return deserializeOption(de, (de) => deserializeMyErrno(de)) + }) as Promise } + +export async function resultSimple () : Promise> { + const out = [] + -export async function returnOptionSugar(): Promise { - const out = [] + return fetch('ipc://localhost/variants/result_simple', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/return_option_sugar', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeOption(de, (de) => deserializeS32(de)) - }) as Promise + return deserializeResult(de, (de) => deserializeU32(de), (de) => deserializeS32(de)) + }) as Promise> } + +export async function isCloneArg (a: IsClone) : Promise { + const out = [] + serializeIsClone(out, a) -export async function returnOptionSugar2(): Promise { - const out = [] - - - return fetch('ipc://localhost/variants/return_option_sugar2', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeOption(de, (de) => deserializeMyErrno(de)) - }) as Promise + fetch('ipc://localhost/variants/is_clone_arg', { method: "POST", body: Uint8Array.from(out) }) } + +export async function isCloneReturn () : Promise { + const out = [] + -export async function resultSimple(): Promise> { - const out = [] + return fetch('ipc://localhost/variants/is_clone_return', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/result_simple', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeResult(de, (de) => deserializeU32(de), (de) => deserializeS32(de)) - }) as Promise> + return deserializeIsClone(de) + }) as Promise } + +export async function returnNamedOption () : Promise { + const out = [] + -export async function isCloneArg(a: IsClone): Promise { - const out = [] - serializeIsClone(out, a) + return fetch('ipc://localhost/variants/return_named_option', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - fetch('ipc://localhost/variants/is_clone_arg', { method: "POST", body: Uint8Array.from(out) }) + return deserializeOption(de, (de) => deserializeU8(de)) + }) as Promise } + +export async function returnNamedResult () : Promise> { + const out = [] + -export async function isCloneReturn(): Promise { - const out = [] + return fetch('ipc://localhost/variants/return_named_result', { method: "POST", body: Uint8Array.from(out) }) + .then(r => r.arrayBuffer()) + .then(bytes => { + const de = new Deserializer(new Uint8Array(bytes)) - - return fetch('ipc://localhost/variants/is_clone_return', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeIsClone(de) - }) as Promise -} - - -export async function returnNamedOption(): Promise { - const out = [] - - - return fetch('ipc://localhost/variants/return_named_option', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeOption(de, (de) => deserializeU8(de)) - }) as Promise -} - - -export async function returnNamedResult(): Promise> { - const out = [] - - - return fetch('ipc://localhost/variants/return_named_result', { method: "POST", body: Uint8Array.from(out) }) - .then(r => r.arrayBuffer()) - .then(bytes => { - const de = new Deserializer(new Uint8Array(bytes)) - - return deserializeResult(de, (de) => deserializeU8(de), (de) => deserializeMyErrno(de)) - }) as Promise> + return deserializeResult(de, (de) => deserializeU8(de), (de) => deserializeMyErrno(de)) + }) as Promise> } + \ No newline at end of file diff --git a/crates/gen-host/src/lib.rs b/crates/gen-host/src/lib.rs index 09f2715..85cd0b9 100644 --- a/crates/gen-host/src/lib.rs +++ b/crates/gen-host/src/lib.rs @@ -34,7 +34,22 @@ pub struct Builder { impl GeneratorBuilder for Builder { fn build(self, interface: Interface) -> Box { - let infos = TypeInfos::collect_from_functions(&interface.typedefs, &interface.functions); + let methods = interface + .typedefs + .iter() + .filter_map(|(_, typedef)| { + if let TypeDefKind::Resource(methods) = &typedef.kind { + Some(methods.iter()) + } else { + None + } + }) + .flatten(); + + let infos = TypeInfos::collect_from_functions( + &interface.typedefs, + interface.functions.iter().chain(methods), + ); Box::new(Host { opts: self, @@ -85,6 +100,7 @@ impl RustGenerator for Host { fn print_resource( &self, + _mod_ident: &str, docs: &str, ident: &proc_macro2::Ident, functions: &[Function], diff --git a/crates/gen-rust/src/lib.rs b/crates/gen-rust/src/lib.rs index de95539..cf804d0 100644 --- a/crates/gen-rust/src/lib.rs +++ b/crates/gen-rust/src/lib.rs @@ -19,6 +19,7 @@ pub trait RustGenerator { fn default_param_mode(&self) -> BorrowMode; fn print_resource( &self, + print_resource: &str, docs: &str, ident: &Ident, functions: &[Function], @@ -63,7 +64,7 @@ pub trait RustGenerator { self.print_union(docs, &ident, cases, info, &borrow_mode) } TypeDefKind::Resource(functions) => { - self.print_resource(docs, &ident, functions, info) + self.print_resource(&self.interface().ident, docs, &ident, functions, info) } };