From eb8befa8c3795337f7e45529be8f5ea6b62729f0 Mon Sep 17 00:00:00 2001 From: thinkerou Date: Sat, 3 Nov 2018 16:16:22 +0800 Subject: [PATCH] remove internal.Params --- binding/binding.go | 8 ++---- binding/binding_test.go | 6 ++--- binding/form_mapping.go | 8 +----- binding/uri.go | 6 ++--- context.go | 9 ++++--- context_test.go | 5 ++-- githubapi_test.go | 10 +++---- internal/internal.go | 34 ------------------------ tree.go | 37 ++++++++++++++++++++++---- tree_test.go | 58 ++++++++++++++++++++--------------------- 10 files changed, 80 insertions(+), 101 deletions(-) delete mode 100644 internal/internal.go diff --git a/binding/binding.go b/binding/binding.go index ec080292..8669ab1e 100644 --- a/binding/binding.go +++ b/binding/binding.go @@ -4,11 +4,7 @@ package binding -import ( - "net/http" - - "github.com/gin-gonic/gin/internal" -) +import "net/http" // Content-Type MIME of the most common data formats. const ( @@ -43,7 +39,7 @@ type BindingBody interface { // but it read the Params. type BindingUri interface { Name() string - BindUri(internal.Params, interface{}) error + BindUri(map[string][]string, interface{}) error } // StructValidator is the minimal interface which needs to be implemented in diff --git a/binding/binding_test.go b/binding/binding_test.go index 67e62838..262f0c5f 100644 --- a/binding/binding_test.go +++ b/binding/binding_test.go @@ -14,7 +14,6 @@ import ( "testing" "time" - "github.com/gin-gonic/gin/internal" "github.com/gin-gonic/gin/testdata/protoexample" "github.com/golang/protobuf/proto" "github.com/stretchr/testify/assert" @@ -654,8 +653,9 @@ func TestUriBinding(t *testing.T) { Name string `uri:"name"` } var tag Tag - params := internal.Params{internal.Param{Key: "name", Value: "thinkerou"}} - assert.NoError(t, b.BindUri(params, &tag)) + m := make(map[string][]string) + m["name"] = []string{"thinkerou"} + assert.NoError(t, b.BindUri(m, &tag)) assert.Equal(t, "thinkerou", tag.Name) } diff --git a/binding/form_mapping.go b/binding/form_mapping.go index 985de7e3..d893c21c 100644 --- a/binding/form_mapping.go +++ b/binding/form_mapping.go @@ -10,15 +10,9 @@ import ( "strconv" "strings" "time" - - "github.com/gin-gonic/gin/internal" ) -func mapUri(ptr interface{}, ps internal.Params) error { - m := make(map[string][]string) - for _, v := range ps { - m[v.Key] = []string{v.Value} - } +func mapUri(ptr interface{}, m map[string][]string) error { return mapFormByTag(ptr, m, "uri") } diff --git a/binding/uri.go b/binding/uri.go index d9204326..f91ec381 100644 --- a/binding/uri.go +++ b/binding/uri.go @@ -4,16 +4,14 @@ package binding -import "github.com/gin-gonic/gin/internal" - type uriBinding struct{} func (uriBinding) Name() string { return "uri" } -func (uriBinding) BindUri(p internal.Params, obj interface{}) error { - if err := mapUri(obj, p); err != nil { +func (uriBinding) BindUri(m map[string][]string, obj interface{}) error { + if err := mapUri(obj, m); err != nil { return err } return validate(obj) diff --git a/context.go b/context.go index 6f058217..df064448 100644 --- a/context.go +++ b/context.go @@ -19,7 +19,6 @@ import ( "github.com/gin-contrib/sse" "github.com/gin-gonic/gin/binding" - "github.com/gin-gonic/gin/internal" "github.com/gin-gonic/gin/render" ) @@ -44,7 +43,7 @@ type Context struct { Request *http.Request Writer ResponseWriter - Params internal.Params + Params Params handlers HandlersChain index int8 @@ -566,7 +565,11 @@ func (c *Context) ShouldBindQuery(obj interface{}) error { // ShouldBindUri binds the passed struct pointer using the specified binding engine. func (c *Context) ShouldBindUri(obj interface{}) error { - return binding.Uri.BindUri(c.Params, obj) + m := make(map[string][]string) + for _, v := range c.Params { + m[v.Key] = []string{v.Value} + } + return binding.Uri.BindUri(m, obj) } // ShouldBindWith binds the passed struct pointer using the specified binding engine. diff --git a/context_test.go b/context_test.go index d4dffbf7..fb492e02 100644 --- a/context_test.go +++ b/context_test.go @@ -20,7 +20,6 @@ import ( "github.com/gin-contrib/sse" "github.com/gin-gonic/gin/binding" - "github.com/gin-gonic/gin/internal" "github.com/golang/protobuf/proto" "github.com/stretchr/testify/assert" "golang.org/x/net/context" @@ -159,7 +158,7 @@ func TestContextReset(t *testing.T) { c.index = 2 c.Writer = &responseWriter{ResponseWriter: httptest.NewRecorder()} - c.Params = internal.Params{internal.Param{}} + c.Params = Params{Param{}} c.Error(errors.New("test")) c.Set("foo", "bar") c.reset() @@ -317,7 +316,7 @@ func TestContextCopy(t *testing.T) { c.index = 2 c.Request, _ = http.NewRequest("POST", "/hola", nil) c.handlers = HandlersChain{func(c *Context) {}} - c.Params = internal.Params{internal.Param{Key: "foo", Value: "bar"}} + c.Params = Params{Param{Key: "foo", Value: "bar"}} c.Set("foo", "bar") cp := c.Copy() diff --git a/githubapi_test.go b/githubapi_test.go index dd5dcbe5..6b56a2b7 100644 --- a/githubapi_test.go +++ b/githubapi_test.go @@ -14,8 +14,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - - "github.com/gin-gonic/gin/internal" ) type route struct { @@ -339,9 +337,9 @@ func TestGithubAPI(t *testing.T) { } } -func exampleFromPath(path string) (string, internal.Params) { +func exampleFromPath(path string) (string, Params) { output := new(bytes.Buffer) - params := make(internal.Params, 0, 6) + params := make(Params, 0, 6) start := -1 for i, c := range path { if c == ':' { @@ -350,7 +348,7 @@ func exampleFromPath(path string) (string, internal.Params) { if start >= 0 { if c == '/' { value := fmt.Sprint(rand.Intn(100000)) - params = append(params, internal.Param{ + params = append(params, Param{ Key: path[start:i], Value: value, }) @@ -364,7 +362,7 @@ func exampleFromPath(path string) (string, internal.Params) { } if start >= 0 { value := fmt.Sprint(rand.Intn(100000)) - params = append(params, internal.Param{ + params = append(params, Param{ Key: path[start:], Value: value, }) diff --git a/internal/internal.go b/internal/internal.go deleted file mode 100644 index 7f5bccb3..00000000 --- a/internal/internal.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2018 Gin Core Team. All rights reserved. -// Use of this source code is governed by a MIT style -// license that can be found in the LICENSE file. - -package internal - -// Param is a single URL parameter, consisting of a key and a value. -type Param struct { - Key string - Value string -} - -// Params is a Param-slice, as returned by the router. -// The slice is ordered, the first URL parameter is also the first slice value. -// It is therefore safe to read values by the index. -type Params []Param - -// Get returns the value of the first Param which key matches the given name. -// If no matching Param is found, an empty string is returned. -func (ps Params) Get(name string) (string, bool) { - for _, entry := range ps { - if entry.Key == name { - return entry.Value, true - } - } - return "", false -} - -// ByName returns the value of the first Param which key matches the given name. -// If no matching Param is found, an empty string is returned. -func (ps Params) ByName(name string) (va string) { - va, _ = ps.Get(name) - return -} diff --git a/tree.go b/tree.go index b46fe0b8..ada62ceb 100644 --- a/tree.go +++ b/tree.go @@ -8,10 +8,37 @@ import ( "net/url" "strings" "unicode" - - "github.com/gin-gonic/gin/internal" ) +// Param is a single URL parameter, consisting of a key and a value. +type Param struct { + Key string + Value string +} + +// Params is a Param-slice, as returned by the router. +// The slice is ordered, the first URL parameter is also the first slice value. +// It is therefore safe to read values by the index. +type Params []Param + +// Get returns the value of the first Param which key matches the given name. +// If no matching Param is found, an empty string is returned. +func (ps Params) Get(name string) (string, bool) { + for _, entry := range ps { + if entry.Key == name { + return entry.Value, true + } + } + return "", false +} + +// ByName returns the value of the first Param which key matches the given name. +// If no matching Param is found, an empty string is returned. +func (ps Params) ByName(name string) (va string) { + va, _ = ps.Get(name) + return +} + type methodTree struct { method string root *node @@ -342,7 +369,7 @@ func (n *node) insertChild(numParams uint8, path string, fullPath string, handle // If no handle can be found, a TSR (trailing slash redirect) recommendation is // made if a handle exists with an extra (without the) trailing slash for the // given path. -func (n *node) getValue(path string, po internal.Params, unescape bool) (handlers HandlersChain, p internal.Params, tsr bool) { +func (n *node) getValue(path string, po Params, unescape bool) (handlers HandlersChain, p Params, tsr bool) { p = po walk: // Outer loop for walking the tree for { @@ -380,7 +407,7 @@ walk: // Outer loop for walking the tree // save param value if cap(p) < int(n.maxParams) { - p = make(internal.Params, 0, n.maxParams) + p = make(Params, 0, n.maxParams) } i := len(p) p = p[:i+1] // expand slice within preallocated capacity @@ -423,7 +450,7 @@ walk: // Outer loop for walking the tree case catchAll: // save param value if cap(p) < int(n.maxParams) { - p = make(internal.Params, 0, n.maxParams) + p = make(Params, 0, n.maxParams) } i := len(p) p = p[:i+1] // expand slice within preallocated capacity diff --git a/tree_test.go b/tree_test.go index 915795e2..ee229933 100644 --- a/tree_test.go +++ b/tree_test.go @@ -10,8 +10,6 @@ import ( "regexp" "strings" "testing" - - "github.com/gin-gonic/gin/internal" ) // Used as a workaround since we can't compare functions or their addressses @@ -27,7 +25,7 @@ type testRequests []struct { path string nilHandler bool route string - ps internal.Params + ps Params } func checkRequests(t *testing.T, tree *node, requests testRequests, unescapes ...bool) { @@ -172,19 +170,19 @@ func TestTreeWildcard(t *testing.T) { checkRequests(t, tree, testRequests{ {"/", false, "/", nil}, - {"/cmd/test/", false, "/cmd/:tool/", internal.Params{internal.Param{Key: "tool", Value: "test"}}}, - {"/cmd/test", true, "", internal.Params{internal.Param{Key: "tool", Value: "test"}}}, - {"/cmd/test/3", false, "/cmd/:tool/:sub", internal.Params{internal.Param{Key: "tool", Value: "test"}, internal.Param{Key: "sub", Value: "3"}}}, - {"/src/", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/"}}}, - {"/src/some/file.png", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/some/file.png"}}}, + {"/cmd/test/", false, "/cmd/:tool/", Params{Param{Key: "tool", Value: "test"}}}, + {"/cmd/test", true, "", Params{Param{Key: "tool", Value: "test"}}}, + {"/cmd/test/3", false, "/cmd/:tool/:sub", Params{Param{Key: "tool", Value: "test"}, Param{Key: "sub", Value: "3"}}}, + {"/src/", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/"}}}, + {"/src/some/file.png", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/some/file.png"}}}, {"/search/", false, "/search/", nil}, - {"/search/someth!ng+in+ünìcodé", false, "/search/:query", internal.Params{internal.Param{Key: "query", Value: "someth!ng+in+ünìcodé"}}}, - {"/search/someth!ng+in+ünìcodé/", true, "", internal.Params{internal.Param{Key: "query", Value: "someth!ng+in+ünìcodé"}}}, - {"/user_gopher", false, "/user_:name", internal.Params{internal.Param{Key: "name", Value: "gopher"}}}, - {"/user_gopher/about", false, "/user_:name/about", internal.Params{internal.Param{Key: "name", Value: "gopher"}}}, - {"/files/js/inc/framework.js", false, "/files/:dir/*filepath", internal.Params{internal.Param{Key: "dir", Value: "js"}, internal.Param{Key: "filepath", Value: "/inc/framework.js"}}}, - {"/info/gordon/public", false, "/info/:user/public", internal.Params{internal.Param{Key: "user", Value: "gordon"}}}, - {"/info/gordon/project/go", false, "/info/:user/project/:project", internal.Params{internal.Param{Key: "user", Value: "gordon"}, internal.Param{Key: "project", Value: "go"}}}, + {"/search/someth!ng+in+ünìcodé", false, "/search/:query", Params{Param{Key: "query", Value: "someth!ng+in+ünìcodé"}}}, + {"/search/someth!ng+in+ünìcodé/", true, "", Params{Param{Key: "query", Value: "someth!ng+in+ünìcodé"}}}, + {"/user_gopher", false, "/user_:name", Params{Param{Key: "name", Value: "gopher"}}}, + {"/user_gopher/about", false, "/user_:name/about", Params{Param{Key: "name", Value: "gopher"}}}, + {"/files/js/inc/framework.js", false, "/files/:dir/*filepath", Params{Param{Key: "dir", Value: "js"}, Param{Key: "filepath", Value: "/inc/framework.js"}}}, + {"/info/gordon/public", false, "/info/:user/public", Params{Param{Key: "user", Value: "gordon"}}}, + {"/info/gordon/project/go", false, "/info/:user/project/:project", Params{Param{Key: "user", Value: "gordon"}, Param{Key: "project", Value: "go"}}}, }) checkPriorities(t, tree) @@ -211,18 +209,18 @@ func TestUnescapeParameters(t *testing.T) { unescape := true checkRequests(t, tree, testRequests{ {"/", false, "/", nil}, - {"/cmd/test/", false, "/cmd/:tool/", internal.Params{internal.Param{Key: "tool", Value: "test"}}}, - {"/cmd/test", true, "", internal.Params{internal.Param{Key: "tool", Value: "test"}}}, - {"/src/some/file.png", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/some/file.png"}}}, - {"/src/some/file+test.png", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/some/file test.png"}}}, - {"/src/some/file++++%%%%test.png", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/some/file++++%%%%test.png"}}}, - {"/src/some/file%2Ftest.png", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/some/file/test.png"}}}, - {"/search/someth!ng+in+ünìcodé", false, "/search/:query", internal.Params{internal.Param{Key: "query", Value: "someth!ng in ünìcodé"}}}, - {"/info/gordon/project/go", false, "/info/:user/project/:project", internal.Params{internal.Param{Key: "user", Value: "gordon"}, internal.Param{Key: "project", Value: "go"}}}, - {"/info/slash%2Fgordon", false, "/info/:user", internal.Params{internal.Param{Key: "user", Value: "slash/gordon"}}}, - {"/info/slash%2Fgordon/project/Project%20%231", false, "/info/:user/project/:project", internal.Params{internal.Param{Key: "user", Value: "slash/gordon"}, internal.Param{Key: "project", Value: "Project #1"}}}, - {"/info/slash%%%%", false, "/info/:user", internal.Params{internal.Param{Key: "user", Value: "slash%%%%"}}}, - {"/info/slash%%%%2Fgordon/project/Project%%%%20%231", false, "/info/:user/project/:project", internal.Params{internal.Param{Key: "user", Value: "slash%%%%2Fgordon"}, internal.Param{Key: "project", Value: "Project%%%%20%231"}}}, + {"/cmd/test/", false, "/cmd/:tool/", Params{Param{Key: "tool", Value: "test"}}}, + {"/cmd/test", true, "", Params{Param{Key: "tool", Value: "test"}}}, + {"/src/some/file.png", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/some/file.png"}}}, + {"/src/some/file+test.png", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/some/file test.png"}}}, + {"/src/some/file++++%%%%test.png", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/some/file++++%%%%test.png"}}}, + {"/src/some/file%2Ftest.png", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/some/file/test.png"}}}, + {"/search/someth!ng+in+ünìcodé", false, "/search/:query", Params{Param{Key: "query", Value: "someth!ng in ünìcodé"}}}, + {"/info/gordon/project/go", false, "/info/:user/project/:project", Params{Param{Key: "user", Value: "gordon"}, Param{Key: "project", Value: "go"}}}, + {"/info/slash%2Fgordon", false, "/info/:user", Params{Param{Key: "user", Value: "slash/gordon"}}}, + {"/info/slash%2Fgordon/project/Project%20%231", false, "/info/:user/project/:project", Params{Param{Key: "user", Value: "slash/gordon"}, Param{Key: "project", Value: "Project #1"}}}, + {"/info/slash%%%%", false, "/info/:user", Params{Param{Key: "user", Value: "slash%%%%"}}}, + {"/info/slash%%%%2Fgordon/project/Project%%%%20%231", false, "/info/:user/project/:project", Params{Param{Key: "user", Value: "slash%%%%2Fgordon"}, Param{Key: "project", Value: "Project%%%%20%231"}}}, }, unescape) checkPriorities(t, tree) @@ -328,9 +326,9 @@ func TestTreeDupliatePath(t *testing.T) { checkRequests(t, tree, testRequests{ {"/", false, "/", nil}, {"/doc/", false, "/doc/", nil}, - {"/src/some/file.png", false, "/src/*filepath", internal.Params{internal.Param{Key: "filepath", Value: "/some/file.png"}}}, - {"/search/someth!ng+in+ünìcodé", false, "/search/:query", internal.Params{internal.Param{Key: "query", Value: "someth!ng+in+ünìcodé"}}}, - {"/user_gopher", false, "/user_:name", internal.Params{internal.Param{Key: "name", Value: "gopher"}}}, + {"/src/some/file.png", false, "/src/*filepath", Params{Param{Key: "filepath", Value: "/some/file.png"}}}, + {"/search/someth!ng+in+ünìcodé", false, "/search/:query", Params{Param{Key: "query", Value: "someth!ng+in+ünìcodé"}}}, + {"/user_gopher", false, "/user_:name", Params{Param{Key: "name", Value: "gopher"}}}, }) }