Skip to content

Commit

Permalink
add http arg get example; some rename
Browse files Browse the repository at this point in the history
  • Loading branch information
RelicOfTesla committed Apr 17, 2024
1 parent 44ec1e3 commit f958f95
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 49 deletions.
25 changes: 12 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
* Thread safely.

## Example:
[http_test.go](dig2/dig2_handler/http_test.go)
[container_test.go](dig2/container_test.go)
[request_di_test.go](dig2/request_di_test.go)
[http_test.go](dig2/dig2_handler/http_test.go)
[container_test.go](dig2/container_test.go)
[request_di_test.go](dig2/request_di_test.go)

```golang
```go

func TestHttpHandler(t *testing.T) {
di := dig2.New()
type test struct {
Expand All @@ -24,30 +25,28 @@ func TestHttpHandler(t *testing.T) {
})

diHandler := dig2_handler.NewHttpHandler(di, dig2_handler.HttpHandlerOpt{
AfterResult: dig2_handler.DefaultHttpJsonApiAfterResult,
AfterRequest: dig2_handler.DefaultHttpJsonApiAfterRequest,
})
http.Handle("/test1", diHandler(func(resp http.ResponseWriter, a test) {
fmt.Fprintf(resp, "%v", a.A)
http.Handle("/test1", diHandler(func(resp http.ResponseWriter, a test, req *http.Request) {
fmt.Fprintf(resp, "%v,%v", a.A, req.FormValue("id"))
}))
http.Handle("/test2", diHandler(func(a test) string {
// auto response from DefaultHttpJsonApiAfterResult
// auto response from DefaultHttpJsonApiAfterRequest
return strconv.Itoa(a.A + 1)
}))
http.Handle("/test3", diHandler(func(a test) test {
// auto response from DefaultHttpJsonApiAfterResult
// auto response from DefaultHttpJsonApiAfterRequest
return test{A: a.A + 2}
}))

srv := httptest.NewServer(nil)

s1 := httpTestGet(t, srv.URL+"/test1")
require.Equal(t, s1, "1")
s1 := httpTestGet(t, srv.URL+"/test1?id=99")
require.Equal(t, s1, "1,99")
s2 := httpTestGet(t, srv.URL+"/test2")
require.Equal(t, s2, "2")
s3 := httpTestGet(t, srv.URL+"/test3")
require.Equal(t, s3, `{"A":3}`)
}

```

# Some TODO
Expand Down
41 changes: 26 additions & 15 deletions dig2/dig2_handler/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dig2_handler

import (
"encoding/json"
"fmt"
"github.com/RelicOfTesla/dig/dig2"
"net/http"
"reflect"
Expand Down Expand Up @@ -35,36 +34,46 @@ func NewHttpHandler(di dig2.IProviderMgr, _opts ...HttpHandlerOpt) func(f any) h
defer func() {
if e := recover(); e != nil {
if err, ok := e.(error); ok && err != nil {
if opt.AfterResult != nil {
opt.AfterResult(resp, req, nil, err)
if opt.AfterRequest != nil {
opt.AfterRequest(resp, req, nil, err)
} else {
panic(e)
}
} else {
panic(e)
}
}
}()
ret, err := caller.StrictCall(
dig2.ArgFrom[http.ResponseWriter](resp),
dig2.ArgFrom[*http.Request](req),
//dig2.ArgFrom[http.ResponseWriter](resp),
//dig2.ArgFrom[*http.Request](req),
dig2.Arg{Type: vtHttpResponseWriter, Value: resp},
dig2.Arg{Type: vtHttpRequest, Value: req},
)
if opt.AfterResult != nil {
opt.AfterResult(resp, req, ret, err)
if opt.AfterRequest != nil {
opt.AfterRequest(resp, req, ret, err)
}
}
}
}

var vtHttpResponseWriter = dig2.TypeFor[http.ResponseWriter]()
var vtHttpRequest = dig2.TypeFor[*http.Request]()

type HttpHandlerOpt struct {
InitBind func(builder *dig2.InvokeBuilder)
BeforeRequest func(resp http.ResponseWriter, req *http.Request) bool
AfterResult func(resp http.ResponseWriter, req *http.Request, results []reflect.Value, err error)
AfterRequest func(resp http.ResponseWriter, req *http.Request, results []reflect.Value, err error)
}

var DefaultHttpJsonOnErr = func(resp http.ResponseWriter, req *http.Request, err error) {
fmt.Fprint(resp, err.Error())
var DefaultHttpJsonApiOnErr = func(resp http.ResponseWriter, req *http.Request, results []reflect.Value, err error) {
if err != nil {
resp.Write([]byte(err.Error()))
//fmt.Fprintf(resp, "%e", err)
}
}

func DefaultHttpJsonApiAfterResult(resp http.ResponseWriter, req *http.Request, results []reflect.Value, err error) {
func DefaultHttpJsonApiAfterRequest(resp http.ResponseWriter, req *http.Request, results []reflect.Value, err error) {
if len(results) > 0 && err == nil {
last := results[len(results)-1]
if last.CanInterface() {
Expand All @@ -74,7 +83,7 @@ func DefaultHttpJsonApiAfterResult(resp http.ResponseWriter, req *http.Request,
}
}
if err != nil {
DefaultHttpJsonOnErr(resp, req, err)
DefaultHttpJsonApiOnErr(resp, req, results, err)
return
}

Expand All @@ -87,16 +96,18 @@ func DefaultHttpJsonApiAfterResult(resp http.ResponseWriter, req *http.Request,
if r0.CanInterface() {
p := r0.Interface()
switch v := p.(type) {
case fmt.Stringer:
fmt.Fprint(resp, v.String())
case interface {
Dispatch(resp http.ResponseWriter)
}:
v.Dispatch(resp)
case interface {
String() string
}:
resp.Write([]byte(v.String()))
default:
cb, err := json.Marshal(p)
if err != nil {
DefaultHttpJsonOnErr(resp, req, err)
DefaultHttpJsonApiOnErr(resp, req, results, err)
} else {
resp.Write(cb)
}
Expand Down
34 changes: 27 additions & 7 deletions dig2/dig2_handler/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,55 @@ import (

func TestHttpHandler(t *testing.T) {
di := dig2.New()

type test struct {
A int
}
di.Provide(func() test {
return test{A: 1}
})

type reqArgId struct {
id int
}
di.Provide(func(req *http.Request) reqArgId {
id, err := strconv.Atoi(req.FormValue("id"))
if err != nil {
panic(err)
}
return reqArgId{
id: id,
}
})

diHandler := dig2_handler.NewHttpHandler(di, dig2_handler.HttpHandlerOpt{
AfterResult: dig2_handler.DefaultHttpJsonApiAfterResult,
AfterRequest: dig2_handler.DefaultHttpJsonApiAfterRequest,
})
http.Handle("/test1", diHandler(func(resp http.ResponseWriter, a test) {
fmt.Fprintf(resp, "%v", a.A)
http.Handle("/test1", diHandler(func(resp http.ResponseWriter, a test, req *http.Request) {
fmt.Fprintf(resp, "%v,%v", a.A, req.FormValue("id"))
}))
http.Handle("/test2", diHandler(func(a test) string {
// auto response from DefaultHttpJsonApiAfterResult
// auto response from DefaultHttpJsonApiAfterRequest
return strconv.Itoa(a.A + 1)
}))
http.Handle("/test3", diHandler(func(a test) test {
// auto response from DefaultHttpJsonApiAfterResult
// auto response from DefaultHttpJsonApiAfterRequest
return test{A: a.A + 2}
}))
http.Handle("/test4", diHandler(func(req reqArgId) test {
// auto response from DefaultHttpJsonApiAfterRequest
return test{A: req.id + 4}
}))
srv := httptest.NewServer(nil)

s1 := httpTestGet(t, srv.URL+"/test1")
require.Equal(t, s1, "1")
s1 := httpTestGet(t, srv.URL+"/test1?id=99")
require.Equal(t, s1, "1,99")
s2 := httpTestGet(t, srv.URL+"/test2")
require.Equal(t, s2, "2")
s3 := httpTestGet(t, srv.URL+"/test3")
require.Equal(t, s3, `{"A":3}`)
s4 := httpTestGet(t, srv.URL+"/test4?id=50")
require.Equal(t, s4, `{"A":54}`)
}

func httpTestGet(t *testing.T, u string) string {
Expand Down
12 changes: 10 additions & 2 deletions dig2/fn_invoker_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ func (x *InvokeBuilder) AddHoldTypeProvider(t TargetKey) error {
return x.scopeHoldTypeProvider.putType(toKey(t))
}
func (x *InvokeBuilder) AddPlaceholderFuncProvider(f any) error {
rf := unwrapDoubleValueOf(f)
tf := rf.Type()
return x.AddPlaceholderFuncProviderEx(unwrapDoubleValueOf(f).Type())
}
func AddPlaceholderFuncProvider[F any](x *InvokeBuilder) error {
var f F
return x.AddPlaceholderFuncProvider(f)
}
func (x *InvokeBuilder) AddPlaceholderFuncProviderEx(tf reflect.Type) error {
if tf.Kind() != reflect.Func {
return errors.New("must func type")
}
inCount := tf.NumIn()
if tf.IsVariadic() && inCount > 0 {
inCount--
Expand Down
10 changes: 1 addition & 9 deletions dig2/uber.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package dig2

import (
"math/rand"
"reflect"
"strings"
)

Expand All @@ -29,15 +28,8 @@ func New(opts ...Option) IProviderMgr {
return newProviderMgr(opt)
}

type IProviderMgr interface {
Invoke(f interface{}) error
Provide(f interface{}, _opts ...ProvideOption) error
type IProviderMgr = *providerMgr

AppendProvider(prov IFindValueCreatorProvider)
CallMust(f interface{}) []reflect.Value
Call(f interface{}) ([]reflect.Value, error)
NewInvokeBuilder() *InvokeBuilder
}
type IFindValueCreatorProvider = iProvider

func newOptions(opts ...Option) *optionImpl {
Expand Down
5 changes: 2 additions & 3 deletions export.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package dig
import "github.com/RelicOfTesla/dig/dig2"

type UBerProviderMgr interface {
Invoke(f interface{}) error
Provide(f interface{}, _opts ...dig2.ProvideOption) error
Invoke(f any) error
Provide(f any, _opts ...dig2.ProvideOption) error
}

func New(opts ...dig2.Option) UBerProviderMgr {
Expand All @@ -17,5 +17,4 @@ type Out = dig2.Out
var Name = dig2.Name
var Group = dig2.Group

//
var Cache = dig2.Cache

0 comments on commit f958f95

Please sign in to comment.