Skip to content

Instantly share code, notes, and snippets.

@estenssoros
Last active December 13, 2019 17:39
Show Gist options
  • Save estenssoros/332598122d88d18d19afd2fd39c438f7 to your computer and use it in GitHub Desktop.
Save estenssoros/332598122d88d18d19afd2fd39c438f7 to your computer and use it in GitHub Desktop.
package asdf
import (
"reflect"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/seaspancode/cds/responses"
)
type DataBaseInterface interface{}
func validateArguments(handler reflect.Type) error {
if handler.NumIn() != 2 {
return errors.Errorf("handler must take two arguments, but have %d", handler.NumIn())
}
databaseType := reflect.TypeOf((*DataBaseInterface)(nil)).Elem()
argumentType := handler.In(0)
if !argumentType.Implements(databaseType) {
return errors.New("first argument does not implement database type")
}
requestType := handler.In(1)
if requestType.Kind() != reflect.Struct {
return errors.New("request is not a struct")
}
return nil
}
func standardHandler(c ContextInterface, request, handlerFunc interface{}) error {
if request == nil {
return errors.New("request is nil")
}
if handlerFunc == nil {
return errors.New("handler is nil")
}
if err := c.Bind(request); err != nil {
return errors.Wrap(err, "bind")
}
handler := reflect.ValueOf(handlerFunc)
handlerType := reflect.TypeOf(handlerFunc)
if handlerType.Kind() != reflect.Func {
return errors.Errorf("handler is %s not func", handlerType.Kind())
}
if err := validateArguments(handlerType); err != nil {
return errors.Wrap(err, "validate arguments")
}
db, ok := c.Value("db").(DataBaseInterface)
if !ok {
return errors.New("context did not contain db interface")
}
args := []reflect.Value{
reflect.ValueOf(db),
reflect.ValueOf(request),
}
response := handler.Call(args)
if len(response) == 0 {
c.JSON(http.StatusNoContent, nil)
return nil
}
if len(response) > 2 {
return errors.New("handler returned more than 2 value")
}
if err, ok := response[len(response)-1].Interface().(error); ok {
c.JSON(http.StatusInternalServerError, err)
return nil
}
if len(response) > 1 {
val := response[0].Interface()
c.JSON(http.StatusOK, val)
return nil
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment