2021-04-22 10:58:51 +02:00
|
|
|
package httpin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"reflect"
|
|
|
|
)
|
|
|
|
|
2021-04-25 13:41:41 +02:00
|
|
|
type Engine struct {
|
|
|
|
inputType reflect.Type
|
|
|
|
queryTag string
|
|
|
|
headerTag string
|
|
|
|
bodyTag string
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewEngine(inputStruct interface{}, opts ...EngineOption) (*Engine, error) {
|
2021-04-22 10:58:51 +02:00
|
|
|
typ := reflect.TypeOf(inputStruct) // retrieve type information
|
|
|
|
if typ.Kind() == reflect.Ptr {
|
|
|
|
typ = typ.Elem()
|
|
|
|
}
|
|
|
|
if typ.Kind() != reflect.Struct {
|
|
|
|
return nil, UnsupportedType(typ.Name())
|
|
|
|
}
|
|
|
|
|
|
|
|
engine := &Engine{
|
|
|
|
inputType: typ,
|
2021-04-25 13:41:41 +02:00
|
|
|
queryTag: "query",
|
|
|
|
headerTag: "header",
|
|
|
|
bodyTag: "body",
|
2021-04-22 10:58:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// if err := engine.build(); err != nil {
|
|
|
|
// return nil, fmt.Errorf("httpin: build: %w", err)
|
|
|
|
// }
|
|
|
|
|
|
|
|
return engine, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Engine) ReadRequest(r *http.Request) (interface{}, error) {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Engine) ReadForm(form url.Values) (interface{}, error) {
|
2021-04-25 13:41:41 +02:00
|
|
|
rv, err := readKeyValues(e.inputType, form, "query")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return rv.Interface(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Engine) ReadHeader(header http.Header) (interface{}, error) {
|
|
|
|
rv, err := readKeyValues(e.inputType, header, "header")
|
2021-04-22 10:58:51 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return rv.Interface(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Engine) ReadBody(body io.Reader) (interface{}, error) {
|
|
|
|
rv := e.newInstance()
|
|
|
|
|
|
|
|
if err := json.NewDecoder(body).Decode(rv.Interface()); err != nil {
|
|
|
|
return nil, fmt.Errorf("httpin: json decode: %w", err)
|
|
|
|
}
|
|
|
|
return rv.Interface(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// newInstance creates a new instance of the input struct.
|
|
|
|
func (e *Engine) newInstance() reflect.Value {
|
|
|
|
return reflect.New(e.inputType)
|
|
|
|
}
|
|
|
|
|
|
|
|
// build builds extractors for the exported fields of the input struct.
|
|
|
|
func (e *Engine) build() error {
|
|
|
|
return errors.New("not implemented")
|
|
|
|
}
|