Skip to content

Commit

Permalink
feat(go-bindgen): flatten result tuples
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Volosatovs <[email protected]>
  • Loading branch information
rvolosatovs committed Sep 25, 2024
1 parent ccf6844 commit 60dbf99
Show file tree
Hide file tree
Showing 21 changed files with 108 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ wasmtime-wasi = { version = "25", default-features = false }
wit-bindgen = { version = "0.30", default-features = false }
wit-bindgen-core = { version = "0.30", default-features = false }
wit-bindgen-wrpc = { version = "0.6.5", default-features = false, path = "./crates/wit-bindgen" }
wit-bindgen-wrpc-go = { version = "0.8.1", default-features = false, path = "./crates/wit-bindgen-go" }
wit-bindgen-wrpc-go = { version = "0.9", default-features = false, path = "./crates/wit-bindgen-go" }
wit-bindgen-wrpc-rust = { version = "0.6.5", default-features = false, path = "./crates/wit-bindgen-rust" }
wit-bindgen-wrpc-rust-macro = { version = "0.6.5", default-features = false, path = "./crates/wit-bindgen-rust-macro" }
wit-component = { version = "0.217", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion crates/wit-bindgen-go/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wit-bindgen-wrpc-go"
version = "0.8.1"
version = "0.9.0"
description = """
Go bindings generator for wRPC
"""
Expand Down
54 changes: 45 additions & 9 deletions crates/wit-bindgen-go/src/interface.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use core::iter;

use std::fmt::Write as _;
use std::mem;

Expand Down Expand Up @@ -49,6 +51,26 @@ fn go_func_name(func: &Function) -> String {
}
}

pub fn flatten_ty<'a>(resolve: &'a Resolve, ty: &Type) -> impl Iterator<Item = Type> + 'a {
let mut ty = *ty;
loop {
if let Type::Id(id) = ty {
match resolve.types[id].kind {
TypeDefKind::Type(t) => {
ty = t;
continue;
}
TypeDefKind::Tuple(ref t) => {
return Box::new(t.types.iter().flat_map(|ty| flatten_ty(resolve, ty)))
as Box<dyn Iterator<Item = Type>>
}
_ => {}
}
}
return Box::new(iter::once(ty)) as Box<dyn Iterator<Item = Type>>;
}
}

pub struct InterfaceGenerator<'a> {
pub src: Source,
pub(super) identifier: Identifier<'a>,
Expand Down Expand Up @@ -2401,8 +2423,12 @@ impl InterfaceGenerator<'_> {
let prev = mem::take(&mut self.src);
self.print_docs_and_params(func);
self.src.push_str(" (");
for ty in func.results.iter_types() {
self.print_opt_ty(ty, true);
for ty in func
.results
.iter_types()
.flat_map(|ty| flatten_ty(self.resolve, ty))
{
self.print_opt_ty(&ty, true);
self.src.push_str(", ");
}
self.push_str("error)\n");
Expand Down Expand Up @@ -2508,11 +2534,16 @@ func ServeInterface(s {wrpc}.Server, h Handler) (stop func() error, err error) {
r#"
{slog}.DebugContext(ctx, "calling `{instance}.{name}` handler")"#,
);
for (i, _) in func.results.iter_types().enumerate() {
let results: Box<[Type]> = func
.results
.iter_types()
.flat_map(|ty| flatten_ty(self.resolve, ty))
.collect();
for (i, _) in results.iter().enumerate() {
uwrite!(self.src, "r{i}, ");
}
self.push_str("err ");
if func.results.len() > 0 {
if results.len() > 0 {
self.push_str(":");
}
self.push_str("= h.");
Expand All @@ -2534,9 +2565,9 @@ func ServeInterface(s {wrpc}.Server, h Handler) (stop func() error, err error) {
var buf {bytes}.Buffer
writes := make(map[uint32]func({wrpc}.IndexWriter) error, {})"#,
func.results.len()
results.len()
);
for (i, ty) in func.results.iter_types().enumerate() {
for (i, ty) in results.iter().enumerate() {
uwrite!(
self.src,
r#"
Expand Down Expand Up @@ -2632,7 +2663,12 @@ func ServeInterface(s {wrpc}.Server, h Handler) (stop func() error, err error) {
self.print_docs_and_params(func);

self.src.push_str(" (");
for (i, ty) in func.results.iter_types().enumerate() {
let results: Box<[Type]> = func
.results
.iter_types()
.flat_map(|ty| flatten_ty(self.resolve, ty))
.collect();
for (i, ty) in results.iter().enumerate() {
uwrite!(self.src, "r{i}__ ");
self.print_opt_ty(ty, true);
self.src.push_str(", ");
Expand Down Expand Up @@ -2735,7 +2771,7 @@ func ServeInterface(s {wrpc}.Server, h Handler) (stop func() error, err error) {
self.src.push_str("nil");
}
self.src.push_str(",\n");
for (i, ty) in func.results.iter_types().enumerate() {
for (i, ty) in results.iter().enumerate() {
let (nested, fut) = async_paths_ty(self.resolve, ty);
for path in nested {
uwrite!(self.src, "{wrpc}.NewSubscribePath().Index({i})");
Expand Down Expand Up @@ -2812,7 +2848,7 @@ func ServeInterface(s {wrpc}.Server, h Handler) (stop func() error, err error) {
func.name,
);

for (i, ty) in func.results.iter_types().enumerate() {
for (i, ty) in results.iter().enumerate() {
uwrite!(
self.src,
"
Expand Down
2 changes: 1 addition & 1 deletion examples/go/hello-client/bindings/client.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// client package contains wRPC bindings for `client` world
package client
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package handler

import (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package handler

import (
Expand Down
2 changes: 1 addition & 1 deletion examples/go/hello-server/bindings/server.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// server package contains wRPC bindings for `server` world
package server

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package resources

import (
Expand Down
2 changes: 1 addition & 1 deletion examples/go/resources-server/bindings/server.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// server package contains wRPC bindings for `server` world
package server

Expand Down
2 changes: 1 addition & 1 deletion examples/go/streams-client/bindings/client.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// client package contains wRPC bindings for `client` world
package client
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package handler

import (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package handler

import (
Expand Down
2 changes: 1 addition & 1 deletion examples/go/streams-server/bindings/server.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// server package contains wRPC bindings for `server` world
package server

Expand Down
2 changes: 1 addition & 1 deletion examples/go/wasi-keyvalue-client/bindings/client.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// client package contains wRPC bindings for `client` world
package client
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package store

import (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
package store

import (
Expand Down
2 changes: 1 addition & 1 deletion examples/go/wasi-keyvalue-server/bindings/server.wrpc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Generated by `wit-bindgen-wrpc-go` 0.8.1. DO NOT EDIT!
// Generated by `wit-bindgen-wrpc-go` 0.9.0. DO NOT EDIT!
// server package contains wRPC bindings for `server` world
package server

Expand Down
15 changes: 6 additions & 9 deletions tests/go/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,8 @@ func (SyncHandler) Fallible(ctx context.Context, ok bool) (*wrpc.Result[bool, st
}
}

func (SyncHandler) Numbers(ctx context.Context) (*wrpc.Tuple10[uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64], error) {
return &wrpc.Tuple10[uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64]{
V0: 1, V1: 2, V2: 3, V3: 4, V4: 5, V5: 6, V6: 7, V7: 8, V8: 9, V9: 10,
}, nil
func (SyncHandler) Numbers(ctx context.Context) (uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64, error) {
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, nil
}

func (SyncHandler) WithFlags(ctx context.Context, a, b, c bool) (*sync.Abc, error) {
Expand Down Expand Up @@ -106,20 +104,19 @@ func (SyncHandler) WithRecordList(ctx context.Context, n uint8) ([]*sync.Rec, er
return vs, nil
}

func (SyncHandler) WithRecordTuple(ctx context.Context) (*wrpc.Tuple2[*sync.Rec, *sync.Rec], error) {
func (SyncHandler) WithRecordTuple(ctx context.Context) (*sync.Rec, *sync.Rec, error) {
slog.DebugContext(ctx, "handling `with-record-tuple`")
return &wrpc.Tuple2[*sync.Rec, *sync.Rec]{
V0: &sync.Rec{
return &sync.Rec{
Nested: &sync.RecNested{
Foo: "0",
},
},
V1: &sync.Rec{
&sync.Rec{
Nested: &sync.RecNested{
Foo: "1",
},
},
}, nil
nil
}

func (SyncHandler) WithEnum(ctx context.Context) (sync.Foobar, error) {
Expand Down
43 changes: 39 additions & 4 deletions tests/go/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,49 @@ func TestSync(t *testing.T) {
}
{
slog.DebugContext(ctx, "calling `wrpc-test:integration/sync.numbers`")
v, err := sync.Numbers(ctx, client)
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, err := sync.Numbers(ctx, client)
if err != nil {
t.Errorf("failed to call `wrpc-test:integration/sync.numbers`: %s", err)
return
}
expected := &wrpc.Tuple10[uint8, uint16, uint32, uint64, int8, int16, int32, int64, float32, float64]{V0: 1, V1: 2, V2: 3, V3: 4, V4: 5, V5: 6, V6: 7, V7: 8, V8: 9, V9: 10}
if !reflect.DeepEqual(v, expected) {
t.Errorf("expected: %v, got: %#v", expected, v)
if v0 != 1 {
t.Errorf("expected: 1, got: %#v", v0)
return
}
if v1 != 2 {
t.Errorf("expected: 2, got: %#v", v1)
return
}
if v2 != 3 {
t.Errorf("expected: 3, got: %#v", v2)
return
}
if v3 != 4 {
t.Errorf("expected: 4, got: %#v", v3)
return
}
if v4 != 5 {
t.Errorf("expected: 5, got: %#v", v4)
return
}
if v5 != 6 {
t.Errorf("expected: 6, got: %#v", v5)
return
}
if v6 != 7 {
t.Errorf("expected: 7, got: %#v", v6)
return
}
if v7 != 8 {
t.Errorf("expected: 8, got: %#v", v7)
return
}
if v8 != 9 {
t.Errorf("expected: 9, got: %#v", v8)
return
}
if v9 != 10 {
t.Errorf("expected: 10, got: %#v", v9)
return
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/wit/test.wit
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface sync {
}

interface async {
with-streams: func(complete: bool) -> (bytes: stream<u8>, lists: stream<list<string>>);
with-streams: func(complete: bool) -> tuple<stream<u8>, stream<list<string>>>;
}

interface resources {
Expand Down

0 comments on commit 60dbf99

Please sign in to comment.