Skip to content

Commit

Permalink
Merge pull request #3 from crackcomm/master
Browse files Browse the repository at this point in the history
Export parameter list
  • Loading branch information
rs committed Mar 9, 2016
2 parents 4ab36e3 + b1a2be0 commit c4b70d5
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 46 deletions.
21 changes: 10 additions & 11 deletions mux.go
Expand Up @@ -128,21 +128,20 @@ type Mux struct {
}

// ParamHolder holds URL parameters.
type ParamHolder struct {
params []param
}
type ParamHolder []Parameter

type param struct {
key string
value string
// Parameter holds URL parameter.
type Parameter struct {
Name string
Value string
}

// 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 ParamHolder) Get(name string) string {
for i := range ps.params {
if ps.params[i].key == name {
return ps.params[i].value
for _, h := range ps {
if h.Name == name {
return h.Value
}
}
return ""
Expand All @@ -152,7 +151,7 @@ type key int

const paramsKey key = iota

var emptyParams = ParamHolder{}
var emptyParams = ParamHolder(nil)

func newParamContext(ctx context.Context, p ParamHolder) context.Context {
return context.WithValue(ctx, paramsKey, p)
Expand Down Expand Up @@ -304,7 +303,7 @@ func (mux *Mux) ServeHTTPC(ctx context.Context, w http.ResponseWriter, r *http.R
path := r.URL.Path

if handler, p, tsr := root.getValue(path); handler != nil {
if len(p.params) > 0 {
if len(p) > 0 {
ctx = newParamContext(ctx, p)
}
handler.ServeHTTPC(ctx, w, r)
Expand Down
28 changes: 10 additions & 18 deletions mux_test.go
Expand Up @@ -30,42 +30,34 @@ func (m *mockResponseWriter) WriteHeader(int) {}

func TestParams(t *testing.T) {
ps := ParamHolder{
params: []param{
{"param1", "value1"},
{"param2", "value2"},
{"param3", "value3"},
},
{"param1", "value1"},
{"param2", "value2"},
{"param3", "value3"},
}
for i := range ps.params {
assert.Equal(t, ps.params[i].value, ps.Get(ps.params[i].key))
for i := range ps {
assert.Equal(t, ps[i].Value, ps.Get(ps[i].Name))
}
assert.Equal(t, "", ps.Get("noKey"), "Expected empty string for not found")
}

func TestParamsDup(t *testing.T) {
ps := ParamHolder{
params: []param{
{"param", "value1"},
{"param", "value2"},
},
{"param", "value1"},
{"param", "value2"},
}
assert.Equal(t, "value1", ps.Get("param"))
}

func TestCtxParams(t *testing.T) {
ps := ParamHolder{
params: []param{{"param1", "value1"}},
}
ps := ParamHolder{{"param1", "value1"}}
ctx := newParamContext(context.TODO(), ps)
assert.Equal(t, "value1", Params(ctx).Get("param1"))
assert.Equal(t, emptyParams, Params(context.TODO()))
assert.Equal(t, emptyParams, Params(nil))
}

func TestCtxParam(t *testing.T) {
ps := ParamHolder{
params: []param{{"param1", "value1"}},
}
ps := ParamHolder{{"param1", "value1"}}
ctx := newParamContext(context.TODO(), ps)
assert.Equal(t, "value1", Param(ctx, "param1"))
assert.Equal(t, "", Param(context.TODO(), "param1"))
Expand All @@ -78,7 +70,7 @@ func TestMux(t *testing.T) {
routed := false
mux.HandleC("GET", "/user/:name", xhandler.HandlerFuncC(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
routed = true
assert.Equal(t, ParamHolder{params: []param{{"name", "gopher"}}}, Params(ctx))
assert.Equal(t, ParamHolder{{"name", "gopher"}}, Params(ctx))
}))

w := new(mockResponseWriter)
Expand Down
26 changes: 13 additions & 13 deletions tree.go
Expand Up @@ -322,7 +322,7 @@ func (n *node) insertChild(numParams uint8, path, fullPath string, handler xhand
// If no handle can be found, a TSR (trailing slash redirect) recommendation is
// made if a handler exists with an extra (without the) trailing slash for the
// given path.
func (n *node) getValue(path string) (handler xhandler.HandlerC, p ParamHolder, tsr bool) {
func (n *node) getValue(path string) (handler xhandler.HandlerC, params ParamHolder, tsr bool) {
walk: // Outer loop for walking the tree
for {
if len(path) > len(n.path) {
Expand Down Expand Up @@ -359,14 +359,14 @@ walk: // Outer loop for walking the tree
}

// save param value
if p.params == nil {
if params == nil {
// lazy allocation
p.params = make([]param, 0, n.maxParams)
params = make(ParamHolder, 0, n.maxParams)
}
i := len(p.params)
p.params = p.params[:i+1] // expand slice within preallocated capacity
p.params[i].key = n.path[1:]
p.params[i].value = path[:end]
i := len(params)
params = params[:i+1] // expand slice within preallocated capacity
params[i].Name = n.path[1:]
params[i].Value = path[:end]

// we need to go deeper!
if end < len(path) {
Expand Down Expand Up @@ -400,14 +400,14 @@ walk: // Outer loop for walking the tree
}

// save param value
if p.params == nil {
if params == nil {
// lazy allocation
p.params = make([]param, 0, n.maxParams)
params = make(ParamHolder, 0, n.maxParams)
}
i := len(p.params)
p.params = p.params[:i+1] // expand slice within preallocated capacity
p.params[i].key = n.path[2:]
p.params[i].value = path
i := len(params)
params = params[:i+1] // expand slice within preallocated capacity
params[i].Name = n.path[2:]
params[i].Value = path
handler = n.handler
return

Expand Down
5 changes: 1 addition & 4 deletions tree_test.go
Expand Up @@ -160,10 +160,7 @@ func TestTreeAddAndGet(t *testing.T) {

func newParams(kv ...string) (ps ParamHolder) {
for i, l := 0, len(kv); i < l; i += 2 {
ps.params = append(ps.params, struct {
key string
value string
}{kv[i], kv[i+1]})
ps = append(ps, Parameter{kv[i], kv[i+1]})
}
return
}
Expand Down

0 comments on commit c4b70d5

Please sign in to comment.