mirror of https://github.com/minio/minio.git
Merge pull request #520 from fkautz/pr_out_updating_godep_deps
This commit is contained in:
commit
f22390ccef
|
@ -7,7 +7,7 @@
|
||||||
"Deps": [
|
"Deps": [
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/dustin/go-humanize",
|
"ImportPath": "github.com/dustin/go-humanize",
|
||||||
"Rev": "8cc1aaa2d955ee82833337cfb10babc42be6bce6"
|
"Rev": "00897f070f09f194c26d65afae734ba4c32404e8"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/golang/groupcache/lru",
|
"ImportPath": "github.com/golang/groupcache/lru",
|
||||||
|
@ -15,11 +15,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gorilla/context",
|
"ImportPath": "github.com/gorilla/context",
|
||||||
"Rev": "50c25fb3b2b3b3cc724e9b6ac75fb44b3bccd0da"
|
"Rev": "215affda49addc4c8ef7e2534915df2c8c35c6cd"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/gorilla/mux",
|
"ImportPath": "github.com/gorilla/mux",
|
||||||
"Rev": "e444e69cbd2e2e3e0749a2f3c717cec491552bbf"
|
"Rev": "660d31f8602b95058fed6833debf113e85350868"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/minio-io/check",
|
"ImportPath": "github.com/minio-io/check",
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
package humanize
|
||||||
|
|
||||||
|
/*
|
||||||
|
Slightly adapted from the source to fit go-humanize.
|
||||||
|
|
||||||
|
Author: https://github.com/gorhill
|
||||||
|
Source: https://gist.github.com/gorhill/5285193
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
renderFloatPrecisionMultipliers = [...]float64{
|
||||||
|
1,
|
||||||
|
10,
|
||||||
|
100,
|
||||||
|
1000,
|
||||||
|
10000,
|
||||||
|
100000,
|
||||||
|
1000000,
|
||||||
|
10000000,
|
||||||
|
100000000,
|
||||||
|
1000000000,
|
||||||
|
}
|
||||||
|
|
||||||
|
renderFloatPrecisionRounders = [...]float64{
|
||||||
|
0.5,
|
||||||
|
0.05,
|
||||||
|
0.005,
|
||||||
|
0.0005,
|
||||||
|
0.00005,
|
||||||
|
0.000005,
|
||||||
|
0.0000005,
|
||||||
|
0.00000005,
|
||||||
|
0.000000005,
|
||||||
|
0.0000000005,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// FormatFloat produces a formatted number as string based on the following user-specified criteria:
|
||||||
|
// * thousands separator
|
||||||
|
// * decimal separator
|
||||||
|
// * decimal precision
|
||||||
|
//
|
||||||
|
// Usage: s := RenderFloat(format, n)
|
||||||
|
// The format parameter tells how to render the number n.
|
||||||
|
//
|
||||||
|
// See examples: http://play.golang.org/p/LXc1Ddm1lJ
|
||||||
|
//
|
||||||
|
// Examples of format strings, given n = 12345.6789:
|
||||||
|
// "#,###.##" => "12,345.67"
|
||||||
|
// "#,###." => "12,345"
|
||||||
|
// "#,###" => "12345,678"
|
||||||
|
// "#\u202F###,##" => "12 345,68"
|
||||||
|
// "#.###,###### => 12.345,678900
|
||||||
|
// "" (aka default format) => 12,345.67
|
||||||
|
//
|
||||||
|
// The highest precision allowed is 9 digits after the decimal symbol.
|
||||||
|
// There is also a version for integer number, FormatInteger(),
|
||||||
|
// which is convenient for calls within template.
|
||||||
|
func FormatFloat(format string, n float64) string {
|
||||||
|
// Special cases:
|
||||||
|
// NaN = "NaN"
|
||||||
|
// +Inf = "+Infinity"
|
||||||
|
// -Inf = "-Infinity"
|
||||||
|
if math.IsNaN(n) {
|
||||||
|
return "NaN"
|
||||||
|
}
|
||||||
|
if n > math.MaxFloat64 {
|
||||||
|
return "Infinity"
|
||||||
|
}
|
||||||
|
if n < -math.MaxFloat64 {
|
||||||
|
return "-Infinity"
|
||||||
|
}
|
||||||
|
|
||||||
|
// default format
|
||||||
|
precision := 2
|
||||||
|
decimalStr := "."
|
||||||
|
thousandStr := ","
|
||||||
|
positiveStr := ""
|
||||||
|
negativeStr := "-"
|
||||||
|
|
||||||
|
if len(format) > 0 {
|
||||||
|
format := []rune(format)
|
||||||
|
|
||||||
|
// If there is an explicit format directive,
|
||||||
|
// then default values are these:
|
||||||
|
precision = 9
|
||||||
|
thousandStr = ""
|
||||||
|
|
||||||
|
// collect indices of meaningful formatting directives
|
||||||
|
formatIndx := []int{}
|
||||||
|
for i, char := range format {
|
||||||
|
if char != '#' && char != '0' {
|
||||||
|
formatIndx = append(formatIndx, i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(formatIndx) > 0 {
|
||||||
|
// Directive at index 0:
|
||||||
|
// Must be a '+'
|
||||||
|
// Raise an error if not the case
|
||||||
|
// index: 0123456789
|
||||||
|
// +0.000,000
|
||||||
|
// +000,000.0
|
||||||
|
// +0000.00
|
||||||
|
// +0000
|
||||||
|
if formatIndx[0] == 0 {
|
||||||
|
if format[formatIndx[0]] != '+' {
|
||||||
|
panic("RenderFloat(): invalid positive sign directive")
|
||||||
|
}
|
||||||
|
positiveStr = "+"
|
||||||
|
formatIndx = formatIndx[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Two directives:
|
||||||
|
// First is thousands separator
|
||||||
|
// Raise an error if not followed by 3-digit
|
||||||
|
// 0123456789
|
||||||
|
// 0.000,000
|
||||||
|
// 000,000.00
|
||||||
|
if len(formatIndx) == 2 {
|
||||||
|
if (formatIndx[1] - formatIndx[0]) != 4 {
|
||||||
|
panic("RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers")
|
||||||
|
}
|
||||||
|
thousandStr = string(format[formatIndx[0]])
|
||||||
|
formatIndx = formatIndx[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// One directive:
|
||||||
|
// Directive is decimal separator
|
||||||
|
// The number of digit-specifier following the separator indicates wanted precision
|
||||||
|
// 0123456789
|
||||||
|
// 0.00
|
||||||
|
// 000,0000
|
||||||
|
if len(formatIndx) == 1 {
|
||||||
|
decimalStr = string(format[formatIndx[0]])
|
||||||
|
precision = len(format) - formatIndx[0] - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate sign part
|
||||||
|
var signStr string
|
||||||
|
if n >= 0.000000001 {
|
||||||
|
signStr = positiveStr
|
||||||
|
} else if n <= -0.000000001 {
|
||||||
|
signStr = negativeStr
|
||||||
|
n = -n
|
||||||
|
} else {
|
||||||
|
signStr = ""
|
||||||
|
n = 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// split number into integer and fractional parts
|
||||||
|
intf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision])
|
||||||
|
|
||||||
|
// generate integer part string
|
||||||
|
intStr := strconv.Itoa(int(intf))
|
||||||
|
|
||||||
|
// add thousand separator if required
|
||||||
|
if len(thousandStr) > 0 {
|
||||||
|
for i := len(intStr); i > 3; {
|
||||||
|
i -= 3
|
||||||
|
intStr = intStr[:i] + thousandStr + intStr[i:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no fractional part, we can leave now
|
||||||
|
if precision == 0 {
|
||||||
|
return signStr + intStr
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate fractional part
|
||||||
|
fracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision]))
|
||||||
|
// may need padding
|
||||||
|
if len(fracStr) < precision {
|
||||||
|
fracStr = "000000000000000"[:precision-len(fracStr)] + fracStr
|
||||||
|
}
|
||||||
|
|
||||||
|
return signStr + intStr + decimalStr + fracStr
|
||||||
|
}
|
||||||
|
|
||||||
|
// FormatInteger produces a formatted number as string.
|
||||||
|
// See FormatFloat.
|
||||||
|
func FormatInteger(format string, n int) string {
|
||||||
|
return FormatFloat(format, float64(n))
|
||||||
|
}
|
78
Godeps/_workspace/src/github.com/dustin/go-humanize/number_test.go
generated
vendored
Normal file
78
Godeps/_workspace/src/github.com/dustin/go-humanize/number_test.go
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package humanize
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TestStruct struct {
|
||||||
|
name string
|
||||||
|
format string
|
||||||
|
num float64
|
||||||
|
formatted string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatFloat(t *testing.T) {
|
||||||
|
tests := []TestStruct{
|
||||||
|
{"default", "", 12345.6789, "12,345.68"},
|
||||||
|
{"#", "#", 12345.6789, "12345.678900000"},
|
||||||
|
{"#.", "#.", 12345.6789, "12346"},
|
||||||
|
{"#,#", "#,#", 12345.6789, "12345,7"},
|
||||||
|
{"#,##", "#,##", 12345.6789, "12345,68"},
|
||||||
|
{"#,###", "#,###", 12345.6789, "12345,679"},
|
||||||
|
{"#,###.", "#,###.", 12345.6789, "12,346"},
|
||||||
|
{"#,###.##", "#,###.##", 12345.6789, "12,345.68"},
|
||||||
|
{"#,###.###", "#,###.###", 12345.6789, "12,345.679"},
|
||||||
|
{"#,###.####", "#,###.####", 12345.6789, "12,345.6789"},
|
||||||
|
{"#.###,######", "#.###,######", 12345.6789, "12.345,678900"},
|
||||||
|
{"#\u202f###,##", "#\u202f###,##", 12345.6789, "12 345,68"},
|
||||||
|
|
||||||
|
// special cases
|
||||||
|
{"NaN", "#", math.NaN(), "NaN"},
|
||||||
|
{"+Inf", "#", math.Inf(1), "Infinity"},
|
||||||
|
{"-Inf", "#", math.Inf(-1), "-Infinity"},
|
||||||
|
{"signStr <= -0.000000001", "", -0.000000002, "-0.00"},
|
||||||
|
{"signStr = 0", "", 0, "0.00"},
|
||||||
|
{"Format directive must start with +", "+000", 12345.6789, "+12345.678900000"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
got := FormatFloat(test.format, test.num)
|
||||||
|
if got != test.formatted {
|
||||||
|
t.Errorf("On %v (%v, %v), got %v, wanted %v",
|
||||||
|
test.name, test.format, test.num, got, test.formatted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Test a single integer
|
||||||
|
got := FormatInteger("#", 12345)
|
||||||
|
if got != "12345.000000000" {
|
||||||
|
t.Errorf("On %v (%v, %v), got %v, wanted %v",
|
||||||
|
"integerTest", "#", 12345, got, "12345.000000000")
|
||||||
|
}
|
||||||
|
// Test the things that could panic
|
||||||
|
panictests := []TestStruct{
|
||||||
|
{"RenderFloat(): invalid positive sign directive", "-", 12345.6789, "12,345.68"},
|
||||||
|
{"RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers", "0.01", 12345.6789, "12,345.68"},
|
||||||
|
}
|
||||||
|
for _, test := range panictests {
|
||||||
|
didPanic := false
|
||||||
|
var message interface{}
|
||||||
|
func() {
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if message = recover(); message != nil {
|
||||||
|
didPanic = true
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// call the target function
|
||||||
|
_ = FormatFloat(test.format, test.num)
|
||||||
|
|
||||||
|
}()
|
||||||
|
if didPanic != true {
|
||||||
|
t.Errorf("On %v, should have panic and did not.",
|
||||||
|
test.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,4 +4,6 @@ go:
|
||||||
- 1.0
|
- 1.0
|
||||||
- 1.1
|
- 1.1
|
||||||
- 1.2
|
- 1.2
|
||||||
|
- 1.3
|
||||||
|
- 1.4
|
||||||
- tip
|
- tip
|
||||||
|
|
|
@ -89,7 +89,7 @@ There are several other matchers that can be added. To match path prefixes:
|
||||||
|
|
||||||
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
|
r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool {
|
||||||
return r.ProtoMajor == 0
|
return r.ProtoMajor == 0
|
||||||
})
|
})
|
||||||
|
|
||||||
...and finally, it is possible to combine several matchers in a single route:
|
...and finally, it is possible to combine several matchers in a single route:
|
||||||
|
|
||||||
|
@ -164,8 +164,8 @@ This also works for host variables:
|
||||||
|
|
||||||
// url.String() will be "http://news.domain.com/articles/technology/42"
|
// url.String() will be "http://news.domain.com/articles/technology/42"
|
||||||
url, err := r.Get("article").URL("subdomain", "news",
|
url, err := r.Get("article").URL("subdomain", "news",
|
||||||
"category", "technology",
|
"category", "technology",
|
||||||
"id", "42")
|
"id", "42")
|
||||||
|
|
||||||
All variables defined in the route are required, and their values must
|
All variables defined in the route are required, and their values must
|
||||||
conform to the corresponding patterns. These requirements guarantee that a
|
conform to the corresponding patterns. These requirements guarantee that a
|
||||||
|
@ -193,7 +193,7 @@ as well:
|
||||||
|
|
||||||
// "http://news.domain.com/articles/technology/42"
|
// "http://news.domain.com/articles/technology/42"
|
||||||
url, err := r.Get("article").URL("subdomain", "news",
|
url, err := r.Get("article").URL("subdomain", "news",
|
||||||
"category", "technology",
|
"category", "technology",
|
||||||
"id", "42")
|
"id", "42")
|
||||||
*/
|
*/
|
||||||
package mux
|
package mux
|
||||||
|
|
|
@ -152,6 +152,13 @@ func (r *Router) getRegexpGroup() *routeRegexpGroup {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Router) buildVars(m map[string]string) map[string]string {
|
||||||
|
if r.parent != nil {
|
||||||
|
m = r.parent.buildVars(m)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Route factories
|
// Route factories
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -224,6 +231,12 @@ func (r *Router) Schemes(schemes ...string) *Route {
|
||||||
return r.NewRoute().Schemes(schemes...)
|
return r.NewRoute().Schemes(schemes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildVars registers a new route with a custom function for modifying
|
||||||
|
// route variables before building a URL.
|
||||||
|
func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route {
|
||||||
|
return r.NewRoute().BuildVarsFunc(f)
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Context
|
// Context
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -135,6 +135,33 @@ func TestHost(t *testing.T) {
|
||||||
path: "",
|
path: "",
|
||||||
shouldMatch: false,
|
shouldMatch: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Path route with single pattern with pipe, match",
|
||||||
|
route: new(Route).Path("/{category:a|b/c}"),
|
||||||
|
request: newRequest("GET", "http://localhost/a"),
|
||||||
|
vars: map[string]string{"category": "a"},
|
||||||
|
host: "",
|
||||||
|
path: "/a",
|
||||||
|
shouldMatch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Path route with single pattern with pipe, match",
|
||||||
|
route: new(Route).Path("/{category:a|b/c}"),
|
||||||
|
request: newRequest("GET", "http://localhost/b/c"),
|
||||||
|
vars: map[string]string{"category": "b/c"},
|
||||||
|
host: "",
|
||||||
|
path: "/b/c",
|
||||||
|
shouldMatch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Path route with multiple patterns with pipe, match",
|
||||||
|
route: new(Route).Path("/{category:a|b/c}/{product}/{id:[0-9]+}"),
|
||||||
|
request: newRequest("GET", "http://localhost/a/product_name/1"),
|
||||||
|
vars: map[string]string{"category": "a", "product": "product_name", "id": "1"},
|
||||||
|
host: "",
|
||||||
|
path: "/a/product_name/1",
|
||||||
|
shouldMatch: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
testRoute(t, test)
|
testRoute(t, test)
|
||||||
|
@ -593,6 +620,39 @@ func TestMatcherFunc(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildVarsFunc(t *testing.T) {
|
||||||
|
tests := []routeTest{
|
||||||
|
{
|
||||||
|
title: "BuildVarsFunc set on route",
|
||||||
|
route: new(Route).Path(`/111/{v1:\d}{v2:.*}`).BuildVarsFunc(func(vars map[string]string) map[string]string {
|
||||||
|
vars["v1"] = "3"
|
||||||
|
vars["v2"] = "a"
|
||||||
|
return vars
|
||||||
|
}),
|
||||||
|
request: newRequest("GET", "http://localhost/111/2"),
|
||||||
|
path: "/111/3a",
|
||||||
|
shouldMatch: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "BuildVarsFunc set on route and parent route",
|
||||||
|
route: new(Route).PathPrefix(`/{v1:\d}`).BuildVarsFunc(func(vars map[string]string) map[string]string {
|
||||||
|
vars["v1"] = "2"
|
||||||
|
return vars
|
||||||
|
}).Subrouter().Path(`/{v2:\w}`).BuildVarsFunc(func(vars map[string]string) map[string]string {
|
||||||
|
vars["v2"] = "b"
|
||||||
|
return vars
|
||||||
|
}),
|
||||||
|
request: newRequest("GET", "http://localhost/1/a"),
|
||||||
|
path: "/2/b",
|
||||||
|
shouldMatch: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
testRoute(t, test)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSubRouter(t *testing.T) {
|
func TestSubRouter(t *testing.T) {
|
||||||
subrouter1 := new(Route).Host("{v1:[a-z]+}.google.com").Subrouter()
|
subrouter1 := new(Route).Host("{v1:[a-z]+}.google.com").Subrouter()
|
||||||
subrouter2 := new(Route).PathPrefix("/foo/{v1}").Subrouter()
|
subrouter2 := new(Route).PathPrefix("/foo/{v1}").Subrouter()
|
||||||
|
|
|
@ -150,11 +150,7 @@ func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// url builds a URL part using the given values.
|
// url builds a URL part using the given values.
|
||||||
func (r *routeRegexp) url(pairs ...string) (string, error) {
|
func (r *routeRegexp) url(values map[string]string) (string, error) {
|
||||||
values, err := mapFromPairs(pairs...)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
urlValues := make([]interface{}, len(r.varsN))
|
urlValues := make([]interface{}, len(r.varsN))
|
||||||
for k, v := range r.varsN {
|
for k, v := range r.varsN {
|
||||||
value, ok := values[v]
|
value, ok := values[v]
|
||||||
|
|
|
@ -31,6 +31,8 @@ type Route struct {
|
||||||
name string
|
name string
|
||||||
// Error resulted from building a route.
|
// Error resulted from building a route.
|
||||||
err error
|
err error
|
||||||
|
|
||||||
|
buildVarsFunc BuildVarsFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match matches the route against the request.
|
// Match matches the route against the request.
|
||||||
|
@ -360,6 +362,19 @@ func (r *Route) Schemes(schemes ...string) *Route {
|
||||||
return r.addMatcher(schemeMatcher(schemes))
|
return r.addMatcher(schemeMatcher(schemes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildVarsFunc --------------------------------------------------------------
|
||||||
|
|
||||||
|
// BuildVarsFunc is the function signature used by custom build variable
|
||||||
|
// functions (which can modify route variables before a route's URL is built).
|
||||||
|
type BuildVarsFunc func(map[string]string) map[string]string
|
||||||
|
|
||||||
|
// BuildVarsFunc adds a custom function to be used to modify build variables
|
||||||
|
// before a route's URL is built.
|
||||||
|
func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route {
|
||||||
|
r.buildVarsFunc = f
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
// Subrouter ------------------------------------------------------------------
|
// Subrouter ------------------------------------------------------------------
|
||||||
|
|
||||||
// Subrouter creates a subrouter for the route.
|
// Subrouter creates a subrouter for the route.
|
||||||
|
@ -422,17 +437,20 @@ func (r *Route) URL(pairs ...string) (*url.URL, error) {
|
||||||
if r.regexp == nil {
|
if r.regexp == nil {
|
||||||
return nil, errors.New("mux: route doesn't have a host or path")
|
return nil, errors.New("mux: route doesn't have a host or path")
|
||||||
}
|
}
|
||||||
|
values, err := r.prepareVars(pairs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
var scheme, host, path string
|
var scheme, host, path string
|
||||||
var err error
|
|
||||||
if r.regexp.host != nil {
|
if r.regexp.host != nil {
|
||||||
// Set a default scheme.
|
// Set a default scheme.
|
||||||
scheme = "http"
|
scheme = "http"
|
||||||
if host, err = r.regexp.host.url(pairs...); err != nil {
|
if host, err = r.regexp.host.url(values); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if r.regexp.path != nil {
|
if r.regexp.path != nil {
|
||||||
if path, err = r.regexp.path.url(pairs...); err != nil {
|
if path, err = r.regexp.path.url(values); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,7 +471,11 @@ func (r *Route) URLHost(pairs ...string) (*url.URL, error) {
|
||||||
if r.regexp == nil || r.regexp.host == nil {
|
if r.regexp == nil || r.regexp.host == nil {
|
||||||
return nil, errors.New("mux: route doesn't have a host")
|
return nil, errors.New("mux: route doesn't have a host")
|
||||||
}
|
}
|
||||||
host, err := r.regexp.host.url(pairs...)
|
values, err := r.prepareVars(pairs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
host, err := r.regexp.host.url(values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -473,7 +495,11 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
|
||||||
if r.regexp == nil || r.regexp.path == nil {
|
if r.regexp == nil || r.regexp.path == nil {
|
||||||
return nil, errors.New("mux: route doesn't have a path")
|
return nil, errors.New("mux: route doesn't have a path")
|
||||||
}
|
}
|
||||||
path, err := r.regexp.path.url(pairs...)
|
values, err := r.prepareVars(pairs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
path, err := r.regexp.path.url(values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -482,6 +508,26 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prepareVars converts the route variable pairs into a map. If the route has a
|
||||||
|
// BuildVarsFunc, it is invoked.
|
||||||
|
func (r *Route) prepareVars(pairs ...string) (map[string]string, error) {
|
||||||
|
m, err := mapFromPairs(pairs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return r.buildVars(m), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Route) buildVars(m map[string]string) map[string]string {
|
||||||
|
if r.parent != nil {
|
||||||
|
m = r.parent.buildVars(m)
|
||||||
|
}
|
||||||
|
if r.buildVarsFunc != nil {
|
||||||
|
m = r.buildVarsFunc(m)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// parentRoute
|
// parentRoute
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -490,6 +536,7 @@ func (r *Route) URLPath(pairs ...string) (*url.URL, error) {
|
||||||
type parentRoute interface {
|
type parentRoute interface {
|
||||||
getNamedRoutes() map[string]*Route
|
getNamedRoutes() map[string]*Route
|
||||||
getRegexpGroup() *routeRegexpGroup
|
getRegexpGroup() *routeRegexpGroup
|
||||||
|
buildVars(map[string]string) map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// getNamedRoutes returns the map where named routes are registered.
|
// getNamedRoutes returns the map where named routes are registered.
|
||||||
|
|
Loading…
Reference in New Issue