From 0a698b902f7aad649b0627c009bd66041f705c25 Mon Sep 17 00:00:00 2001 From: olongfen <824426699@qq.com> Date: Tue, 5 Jul 2022 19:45:11 +0800 Subject: [PATCH] add: params parse (#1964) --- ctx.go | 10 ++++++++++ ctx_test.go | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/ctx.go b/ctx.go index 81c62190c9..2487eb4214 100644 --- a/ctx.go +++ b/ctx.go @@ -39,6 +39,7 @@ const ( queryTag = "query" reqHeaderTag = "reqHeader" bodyTag = "form" + uriTag = "uri" ) // userContextKey define the key name for storing context.Context in *fasthttp.RequestCtx @@ -854,6 +855,15 @@ func (c *Ctx) AllParams() map[string]string { return params } +// ParamsParser binds the param string to a struct. +func (c *Ctx) ParamsParser(out interface{}) error { + params := make(map[string][]string, len(c.route.Params)) + for _, param := range c.route.Params { + params[param] = append(params[param], c.Params(param)) + } + return c.parseToStruct(uriTag, out, params) +} + // ParamsInt is used to get an integer from the route parameters // it defaults to zero if the parameter is not found or if the // parameter cannot be converted to an integer diff --git a/ctx_test.go b/ctx_test.go index e593af531d..9f092327b5 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -426,6 +426,29 @@ func Test_Ctx_BodyParser(t *testing.T) { utils.AssertEqual(t, "doe", cq.Data[1].Name) } +func Test_Ctx_ParamParser(t *testing.T) { + t.Parallel() + app := New() + app.Get("/test1/userId/role/:roleId", func(ctx *Ctx) error { + type Demo struct { + UserID uint `uri:"userId"` + RoleID uint `uri:"roleId"` + } + var ( + d = new(Demo) + ) + if err := ctx.ParamsParser(d); err != nil { + t.Fatal(err) + } + utils.AssertEqual(t, uint(111), d.UserID) + utils.AssertEqual(t, uint(222), d.RoleID) + return nil + }) + app.Test(httptest.NewRequest(MethodGet, "/test1/111/role/222", nil)) + app.Test(httptest.NewRequest(MethodGet, "/test2/111/role/222", nil)) + +} + // go test -run Test_Ctx_BodyParser_WithSetParserDecoder func Test_Ctx_BodyParser_WithSetParserDecoder(t *testing.T) { type CustomTime time.Time @@ -1433,6 +1456,36 @@ func Benchmark_Ctx_AllParams(b *testing.B) { res) } +// go test -v -run=^$ -bench=Benchmark_Ctx_ParamsParse -benchmem -count=4 +func Benchmark_Ctx_ParamsParse(b *testing.B) { + app := New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + c.route = &Route{ + Params: []string{ + "param1", "param2", "param3", "param4", + }, + } + c.values = [maxParams]string{ + "john", "doe", "is", "awesome", + } + var res struct { + Param1 string `uri:"param1"` + Param2 string `uri:"param2"` + Param3 string `uri:"param3"` + Param4 string `uri:"param4"` + } + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + c.ParamsParser(&res) + } + utils.AssertEqual(b, "john", res.Param1) + utils.AssertEqual(b, "doe", res.Param2) + utils.AssertEqual(b, "is", res.Param3) + utils.AssertEqual(b, "awesome", res.Param4) +} + // go test -run Test_Ctx_Path func Test_Ctx_Path(t *testing.T) { t.Parallel() @@ -2896,7 +2949,7 @@ func Test_Ctx_SendStream(t *testing.T) { file, err := os.Open("./.github/index.html") utils.AssertEqual(t, nil, err) c.SendStream(bufio.NewReader(file)) - utils.AssertEqual(t, true, (c.Response().Header.ContentLength() > 200)) + utils.AssertEqual(t, true, c.Response().Header.ContentLength() > 200) } // go test -run Test_Ctx_Set