2020-03-29 13:00:22 +00:00
|
|
|
package dynamic
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
|
|
|
|
"git.xdrm.io/go/aicra/internal/config"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Build a handler from a service configuration and a HandlerFn
|
|
|
|
//
|
|
|
|
// a HandlerFn must have as a signature : `func(api.Request, inputStruct) (outputStruct, api.Error)`
|
|
|
|
// - `inputStruct` is a struct{} containing a field for each service input (with valid reflect.Type)
|
|
|
|
// - `outputStruct` is a struct{} containing a field for each service output (with valid reflect.Type)
|
|
|
|
//
|
|
|
|
// Special cases:
|
|
|
|
// - it there is no input, `inputStruct` can be omitted
|
|
|
|
// - it there is no output, `outputStruct` can be omitted
|
|
|
|
func Build(fn HandlerFn, service config.Service) (*Handler, error) {
|
|
|
|
h := &Handler{
|
|
|
|
spec: makeSpec(service),
|
|
|
|
fn: fn,
|
|
|
|
}
|
|
|
|
|
2020-03-29 14:58:53 +00:00
|
|
|
fnv := reflect.ValueOf(fn)
|
2020-03-29 13:00:22 +00:00
|
|
|
|
2020-03-29 14:58:53 +00:00
|
|
|
if fnv.Type().Kind() != reflect.Func {
|
2020-03-29 13:00:22 +00:00
|
|
|
return nil, ErrHandlerNotFunc
|
|
|
|
}
|
|
|
|
|
2020-03-29 14:58:53 +00:00
|
|
|
if err := h.spec.checkInput(fnv); err != nil {
|
2020-03-29 13:00:22 +00:00
|
|
|
return nil, fmt.Errorf("input: %w", err)
|
|
|
|
}
|
2020-03-29 14:58:53 +00:00
|
|
|
if err := h.spec.checkOutput(fnv); err != nil {
|
2020-03-29 13:00:22 +00:00
|
|
|
return nil, fmt.Errorf("output: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return h, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle
|
|
|
|
func (h *Handler) Handle() {
|
|
|
|
|
|
|
|
}
|