sync from project
This commit is contained in:
44
inject.go
44
inject.go
@ -12,10 +12,13 @@ import (
|
||||
"git.jeffthecoder.xyz/public/lazyhandler/util"
|
||||
)
|
||||
|
||||
type ErrArgumentIsNotExtractable int
|
||||
type ErrArgumentIsNotExtractable struct {
|
||||
Index int
|
||||
Type reflect.Type
|
||||
}
|
||||
|
||||
func (err ErrArgumentIsNotExtractable) Error() string {
|
||||
return fmt.Sprintf("argument %v is not extractable", int(err))
|
||||
return fmt.Sprintf("argument %v is not extractable: %s", err.Index, err.Type.String())
|
||||
}
|
||||
|
||||
type ErrReturnValueNotConvertableIntoResponsePart int
|
||||
@ -27,6 +30,7 @@ func (err ErrReturnValueNotConvertableIntoResponsePart) Error() string {
|
||||
var (
|
||||
ErrNotAFunc = errors.New("not a function")
|
||||
ErrDuplicateResponseWriterExtractor = errors.New("duplicate response writer extractor")
|
||||
ErrDuplicateRequestBodyExtractor = errors.New("duplicate request body extractor")
|
||||
ErrResponseWriterCannotBeExtracted = errors.New("http.ResponseWriter extractor must not exists if function has return value")
|
||||
)
|
||||
|
||||
@ -50,6 +54,7 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
}
|
||||
|
||||
responseWriterExtracted := -1
|
||||
requestBodyExtracted := -1
|
||||
|
||||
extractors := make([]func(http.ResponseWriter, *http.Request) (any, error), t.NumIn())
|
||||
for idx := 0; idx < t.NumIn(); idx++ {
|
||||
@ -57,7 +62,10 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
|
||||
extractor, isTakeResponseWriter := magic.GetExtractor(in)
|
||||
if extractor == nil {
|
||||
return nil, ErrArgumentIsNotExtractable(idx)
|
||||
return nil, ErrArgumentIsNotExtractable{
|
||||
Index: idx,
|
||||
Type: in,
|
||||
}
|
||||
}
|
||||
if isTakeResponseWriter {
|
||||
if responseWriterExtracted >= 0 {
|
||||
@ -65,6 +73,14 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
}
|
||||
responseWriterExtracted = idx
|
||||
}
|
||||
|
||||
if magic.IsTakeBody(in) {
|
||||
if requestBodyExtracted >= 0 {
|
||||
return nil, ErrDuplicateRequestBodyExtractor
|
||||
}
|
||||
requestBodyExtracted = idx
|
||||
}
|
||||
|
||||
extractors[idx] = extractor
|
||||
}
|
||||
|
||||
@ -98,6 +114,14 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
if _, ok := util.Implements[magic.RespondWriter](out); ok {
|
||||
continue
|
||||
}
|
||||
if _, ok := util.Implements[magic.RespondWriter](reflect.PointerTo(out)); ok {
|
||||
continue
|
||||
}
|
||||
if out.Kind() == reflect.Pointer {
|
||||
if _, ok := util.Implements[magic.RespondWriter](out.Elem()); ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// last is error
|
||||
if _, ok := util.Implements[error](out); ok && idx == t.NumOut()-1 {
|
||||
@ -108,12 +132,6 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var closers []io.Closer
|
||||
defer func() {
|
||||
for _, closer := range closers {
|
||||
closer.Close()
|
||||
}
|
||||
}()
|
||||
in := make([]reflect.Value, len(extractors))
|
||||
for idx, extractor := range extractors {
|
||||
v, err := extractor(w, r)
|
||||
@ -128,9 +146,6 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
if closer, ok := v.(io.Closer); ok {
|
||||
defer closer.Close()
|
||||
}
|
||||
in[idx] = reflect.ValueOf(v)
|
||||
}
|
||||
values := funcValue.Call(in)
|
||||
@ -169,6 +184,11 @@ func MagicHandler(fn any) (http.Handler, error) {
|
||||
continue
|
||||
}
|
||||
responseWriter.WriteResponse(w)
|
||||
} else if responseWriter, ok := util.Implements[magic.RespondWriter](&value); ok {
|
||||
if responseWriter == nil {
|
||||
continue
|
||||
}
|
||||
responseWriter.WriteResponse(w)
|
||||
} else if headers, ok := obj.(http.Header); ok { // not
|
||||
for name, values := range headers {
|
||||
for idx, value := range values {
|
||||
|
Reference in New Issue
Block a user