Skip to content

Commit

Permalink
Fix decoding requests of type pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
diamondburned committed Apr 21, 2024
1 parent abf58de commit 86ff8f6
Showing 1 changed file with 35 additions and 5 deletions.
40 changes: 35 additions & 5 deletions hrt.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package hrt
import (
"context"
"net/http"
"reflect"
)

type ctxKey uint8
Expand Down Expand Up @@ -81,11 +82,11 @@ func (h Handler[RequestT, ResponseT]) ServeHTTP(w http.ResponseWriter, r *http.R
ctx := context.WithValue(r.Context(), requestCtxKey, r)

opts := OptsFromContext(ctx)
if _, ok := any(req).(None); !ok {
if err := opts.Encoder.Decode(r, &req); err != nil {
opts.ErrorWriter.WriteError(w, WrapHTTPError(http.StatusBadRequest, err))
return
}

req, err := decodeRequest[RequestT](r, opts)
if err != nil {
opts.ErrorWriter.WriteError(w, WrapHTTPError(http.StatusBadRequest, err))
return
}

resp, err := h(ctx, req)
Expand All @@ -101,3 +102,32 @@ func (h Handler[RequestT, ResponseT]) ServeHTTP(w http.ResponseWriter, r *http.R
}
}
}

func decodeRequest[RequestT any](r *http.Request, opts Opts) (RequestT, error) {
var req RequestT
if _, ok := any(req).(None); ok {
return req, nil
}

if reflect.TypeFor[RequestT]().Kind() == reflect.Ptr {
// RequestT is a pointer type, so we need to allocate a new instance.
v := reflect.New(reflect.TypeFor[RequestT]().Elem()).Interface()

if err := opts.Encoder.Decode(r, v); err != nil {
return req, err
}

// Return the value as-is, since it's already a pointer.
return v.(RequestT), nil
}

// RequestT is a value type, so we need to allocate a new pointer instance
// and dereference it afterwards.
v := reflect.New(reflect.TypeFor[RequestT]()).Interface()

if err := opts.Encoder.Decode(r, v); err != nil {
return req, err
}

return *v.(*RequestT), nil
}

0 comments on commit 86ff8f6

Please sign in to comment.