diff --git a/lambda/entry.go b/lambda/entry.go index 6c1d7194..159c7f9f 100644 --- a/lambda/entry.go +++ b/lambda/entry.go @@ -17,20 +17,23 @@ import ( // - handler must be a function // - handler may take between 0 and two arguments. // - if there are two arguments, the first argument must satisfy the "context.Context" interface. -// - handler may return between 0 and two arguments. -// - if there are two return values, the second argument must be an error. +// - handler may return between 0 and two values. +// - if there are two return values, the second return value must be an error. // - if there is one return value it must be an error. // // Valid function signatures: // // func () +// func (TIn) // func () error // func (TIn) error // func () (TOut, error) // func (TIn) (TOut, error) +// func (context.Context) // func (context.Context) error -// func (context.Context, TIn) error // func (context.Context) (TOut, error) +// func (context.Context, TIn) +// func (context.Context, TIn) error // func (context.Context, TIn) (TOut, error) // // Where "TIn" and "TOut" are types compatible with the "encoding/json" standard library. diff --git a/lambda/entry_generic.go b/lambda/entry_generic.go new file mode 100644 index 00000000..08bcdf20 --- /dev/null +++ b/lambda/entry_generic.go @@ -0,0 +1,23 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved + +package lambda + +import ( + "context" +) + +// HandlerFunc represents a valid input with two arguments and two returns as described by Start +type HandlerFunc[TIn, TOut any] interface { + func(context.Context, TIn) (TOut, error) +} + +// StartHandlerFunc is the same as StartWithOptions except that it takes a generic input +// so that the function signature can be validated at compile time. +// +// Currently only the `func (context.Context, TIn) (TOut, error)` variant is supported +func StartHandlerFunc[TIn any, TOut any, H HandlerFunc[TIn, TOut]](handler H, options ...Option) { + start(newHandler(handler, options...)) +} diff --git a/lambda/entry_generic_test.go b/lambda/entry_generic_test.go new file mode 100644 index 00000000..a1bc5acc --- /dev/null +++ b/lambda/entry_generic_test.go @@ -0,0 +1,36 @@ +//go:build go1.18 +// +build go1.18 + +// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved + +package lambda + +import ( + "context" + "fmt" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStartHandlerFunc(t *testing.T) { + actual := "unexpected" + logFatalf = func(format string, v ...interface{}) { + actual = fmt.Sprintf(format, v...) + } + + f := func(context.Context, any) (any, error) { return 1, nil } + StartHandlerFunc(f) + + assert.Equal(t, "expected AWS Lambda environment variables [_LAMBDA_SERVER_PORT AWS_LAMBDA_RUNTIME_API] are not defined", actual) + + handlerType := reflect.TypeOf(f) + + handlerTakesContext, err := validateArguments(handlerType) + assert.NoError(t, err) + assert.True(t, handlerTakesContext) + + err = validateReturns(handlerType) + assert.NoError(t, err) +}