~samwhited/mux

9f0dd166b594f9e4ff5e88e011740e003307aa51 — Sam Whited 1 year, 7 months ago 2a6d65f
mux: add route information to param metadata
3 files changed, 37 insertions(+), 19 deletions(-)

M node.go
M params.go
M params_test.go
M node.go => node.go +8 -6
@@ 23,7 23,7 @@ func (n *node) match(path string, offset uint, r *http.Request) (part string, re
	// wildcards are a special case that always match the entire remainder of the
	// path.
	if n.typ == typWild {
		r = addValue(r, n.name, path, offset, path)
		r = addValue(r, n.name, n.typ, path, offset, path)
		return path, "", r
	}



@@ 35,37 35,39 @@ func (n *node) match(path string, offset uint, r *http.Request) (part string, re
		}
		return "", path, r
	case typString:
		r = addValue(r, n.name, part, offset, part)
		r = addValue(r, n.name, n.typ, part, offset, part)
		return part, remain, r
	case typUint:
		v, err := strconv.ParseUint(part, 10, 64)
		if err != nil {
			return "", path, r
		}
		r = addValue(r, n.name, part, offset, v)
		r = addValue(r, n.name, n.typ, part, offset, v)
		return part, remain, r
	case typInt:
		v, err := strconv.ParseInt(part, 10, 64)
		if err != nil {
			return "", path, r
		}
		r = addValue(r, n.name, part, offset, v)
		r = addValue(r, n.name, n.typ, part, offset, v)
		return part, remain, r
	case typFloat:
		v, err := strconv.ParseFloat(part, 64)
		if err != nil {
			return "", path, r
		}
		r = addValue(r, n.name, part, offset, v)
		r = addValue(r, n.name, n.typ, part, offset, v)
		return part, remain, r
	}
	panic("unknown type")
}

func addValue(r *http.Request, name, raw string, offset uint, val interface{}) *http.Request {
func addValue(r *http.Request, name, typ, raw string, offset uint, val interface{}) *http.Request {
	pinfo := ParamInfo{
		Value:  val,
		Raw:    raw,
		Name:   name,
		Type:   typ,
		Offset: offset,
	}
	if name != "" {

M params.go => params.go +6 -0
@@ 10,6 10,12 @@ type ParamInfo struct {
	Value interface{}
	// The raw value of the parameter (for example "10")
	Raw string
	// The name of the route component that the parameter was matched against (for
	// example "name" in "{name int}")
	Name string
	// Type type of the route component that the parameter was matched against
	// (for example "int" in "{name int}")
	Type string
	// The offset in the path where this parameter was found (for example if "10"
	// is parsed out of the path "/10" the offset is 1)
	Offset uint

M params_test.go => params_test.go +23 -13
@@ 22,31 22,39 @@ func TestInvalidType(t *testing.T) {
var paramsTests = [...]struct {
	routes  []string
	path    string
	params  map[string]mux.ParamInfo
	params  []mux.ParamInfo
	noMatch bool
}{
	0: {
		routes: []string{"/user/{account uint}/{user int}/{name string}/{f float}"},
		path:   "/user/123/-11/me/1.123",
		params: map[string]mux.ParamInfo{
			"account": mux.ParamInfo{
		params: []mux.ParamInfo{
			mux.ParamInfo{
				Value:  uint64(123),
				Raw:    "123",
				Name:   "account",
				Type:   "uint",
				Offset: 6,
			},
			"user": mux.ParamInfo{
			mux.ParamInfo{
				Value:  int64(-11),
				Raw:    "-11",
				Name:   "user",
				Type:   "int",
				Offset: 10,
			},
			"name": mux.ParamInfo{
			mux.ParamInfo{
				Value:  "me",
				Raw:    "me",
				Name:   "name",
				Type:   "string",
				Offset: 14,
			},
			"f": mux.ParamInfo{
			mux.ParamInfo{
				Value:  float64(1.123),
				Raw:    "1.123",
				Name:   "f",
				Type:   "float",
				Offset: 17,
			},
		},


@@ 59,10 67,12 @@ var paramsTests = [...]struct {
	2: {
		routes: []string{"/one/{other path}"},
		path:   "/one/two/three",
		params: map[string]mux.ParamInfo{
			"other": mux.ParamInfo{
		params: []mux.ParamInfo{
			mux.ParamInfo{
				Value:  "two/three",
				Raw:    "two/three",
				Name:   "other",
				Type:   "path",
				Offset: 5,
			},
		},


@@ 86,17 96,17 @@ const (
	notFoundStatusCode = 43
)

func paramsHandler(t *testing.T, params map[string]mux.ParamInfo) http.HandlerFunc {
func paramsHandler(t *testing.T, params []mux.ParamInfo) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(testStatusCode)
		for k, v := range params {
			pinfo, ok := mux.Param(r, k)
		for _, v := range params {
			pinfo, ok := mux.Param(r, v.Name)
			if !ok {
				t.Errorf("No such parameter found %q", k)
				t.Errorf("No such parameter found %q", v.Name)
				continue
			}
			if !reflect.DeepEqual(pinfo, v) {
				t.Errorf("Param do not match for %q, want=%+v, got=%+v)", k, v, pinfo)
				t.Errorf("Param do not match: want=%+v, got=%+v)", v, pinfo)
			}
		}
	}