From 47802359f91d3f47208b66ac52aac702136e92bd Mon Sep 17 00:00:00 2001 From: "M. J. Fromberger" Date: Tue, 26 Oct 2021 09:19:38 -0700 Subject: [PATCH] Remove support for variadic handlers. This was mostly a parlor trick (i.e., done because it could be). Because handlers are called by the server, there is no real syntactic benefit for the implementation. Get rid of the special case and simplify the API. --- handler/handler.go | 14 +++----------- handler/handler_test.go | 5 +---- jhttp/example_test.go | 2 +- jrpc2_test.go | 4 ++-- 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/handler/handler.go b/handler/handler.go index 975dd12..921d18a 100644 --- a/handler/handler.go +++ b/handler/handler.go @@ -102,7 +102,6 @@ var ( type FuncInfo struct { Type reflect.Type // the complete function type Argument reflect.Type // the non-context argument type, or nil - IsVariadic bool // true if the function is variadic on its argument Result reflect.Type // the non-error result type, or nil ReportsError bool // true if the function reports an error strictFields bool // enforce strict field checking @@ -214,12 +213,7 @@ func (fi *FuncInfo) Wrap() Func { } } - f := reflect.ValueOf(fi.fn) - call := f.Call - if fi.IsVariadic { - call = f.CallSlice - } - + call := reflect.ValueOf(fi.fn).Call return Func(func(ctx context.Context, req *jrpc2.Request) (interface{}, error) { args, ierr := newInput(reflect.ValueOf(ctx), req) if ierr != nil { @@ -239,9 +233,6 @@ func (fi *FuncInfo) Wrap() Func { // func(context.Context, X) error // func(context.Context, X) Y // func(context.Context, X) (Y, error) -// func(context.Context, ...X) error -// func(context.Context, ...X) Y -// func(context.Context, ...X) (Y, error) // func(context.Context, *jrpc2.Request) error // func(context.Context, *jrpc2.Request) Y // func(context.Context, *jrpc2.Request) (Y, error) @@ -277,9 +268,10 @@ func Check(fn interface{}) (*FuncInfo, error) { return nil, errors.New("wrong number of parameters") } else if info.Type.In(0) != ctxType { return nil, errors.New("first parameter is not context.Context") + } else if info.Type.IsVariadic() { + return nil, errors.New("variadic functions are not supported") } else if np == 2 { info.Argument = info.Type.In(1) - info.IsVariadic = info.Type.IsVariadic() } // Check return values. diff --git a/handler/handler_test.go b/handler/handler_test.go index 0e0eb0d..5963323 100644 --- a/handler/handler_test.go +++ b/handler/handler_test.go @@ -15,7 +15,7 @@ import ( func y1(context.Context) (int, error) { return 0, nil } -func y2(_ context.Context, vs ...int) (int, error) { return len(vs), nil } +func y2(_ context.Context, vs []int) (int, error) { return len(vs), nil } func y3(context.Context) error { return errors.New("blah") } @@ -41,9 +41,6 @@ func TestCheck(t *testing.T) { {v: func(context.Context, []int) error { return nil }}, {v: func(context.Context, []bool) (float64, error) { return 0, nil }}, {v: func(context.Context, *argStruct) int { return 0 }}, - {v: func(context.Context, ...int) error { return nil }}, - {v: func(context.Context, ...int) bool { return true }}, - {v: func(context.Context, ...string) (bool, error) { return false, nil }}, {v: func(context.Context, *jrpc2.Request) error { return nil }}, {v: func(context.Context, *jrpc2.Request) float64 { return 0 }}, {v: func(context.Context, *jrpc2.Request) (byte, error) { return '0', nil }}, diff --git a/jhttp/example_test.go b/jhttp/example_test.go index a3b87d1..9595440 100644 --- a/jhttp/example_test.go +++ b/jhttp/example_test.go @@ -16,7 +16,7 @@ import ( func Example() { // Set up a bridge to demonstrate the API. b := jhttp.NewBridge(handler.Map{ - "Test": handler.New(func(ctx context.Context, ss ...string) (string, error) { + "Test": handler.New(func(ctx context.Context, ss []string) (string, error) { return strings.Join(ss, " "), nil }), }, nil) diff --git a/jrpc2_test.go b/jrpc2_test.go index c7eb95b..3a86dd5 100644 --- a/jrpc2_test.go +++ b/jrpc2_test.go @@ -65,8 +65,8 @@ func (dummy) Mul(_ context.Context, req struct{ X, Y int }) (int, error) { return req.X * req.Y, nil } -// Max has a variadic signature. -func (dummy) Max(_ context.Context, vs ...int) (int, error) { +// Max takes a slice of arguments. +func (dummy) Max(_ context.Context, vs []int) (int, error) { if len(vs) == 0 { return 0, jrpc2.Errorf(code.InvalidParams, "cannot compute max of no elements") }