Skip to content

Commit 0fad880

Browse files
committed
Change root package name and key field name to token
1 parent d35c813 commit 0fad880

File tree

4 files changed

+208
-200
lines changed

4 files changed

+208
-200
lines changed

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ Thanks to [path-to-regexp](https://github.com/pillarjs/path-to-regexp).
1515
```go
1616
import pathToRegexp "github/soongo/path-to-regexp"
1717

18-
// pathToRegexp.PathToRegexp(path, keys, options) // keys and options can be nil
18+
// pathToRegexp.PathToRegexp(path, tokens, options) // tokens and options can be nil
1919
// pathToRegexp.Parse(path, options) // options can be nil
2020
// pathToRegexp.Compile(path, options) // options can be nil
2121
```
2222

2323
- **path** A string, array or slice of strings, or a regular expression with type *github.com/dlclark/regexp2.Regexp.
24-
- **keys** An array to populate with keys found in the path.
25-
- key
24+
- **tokens** An array to populate with tokens found in the path.
25+
- token
2626
- **name** The name of the token (`string` for named or `number` for index)
2727
- **prefix** The prefix character for the segment (e.g. `/`)
2828
- **delimiter** The delimiter for the segment (same as prefix or default delimiter)
@@ -39,25 +39,25 @@ import pathToRegexp "github/soongo/path-to-regexp"
3939
- **whitelist** List of characters to consider delimiters when parsing. (default: `nil`, any character)
4040

4141
```go
42-
var keys []pathToRegexp.Key
43-
regexp, err := pathToRegexp.PathToRegexp("/foo/:bar", &keys, nil)
42+
var tokens []pathToRegexp.Token
43+
regexp, err := pathToRegexp.PathToRegexp("/foo/:bar", &tokens, nil)
4444
// regexp: ^\/foo\/([^\/]+?)(?:\/)?$
45-
// keys: [{name:"bar", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"}}]
45+
// tokens: [{name:"bar", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"}}]
4646
```
4747

4848
**Please note:** The `Regexp` returned by `path-to-regexp` is intended for ordered data (e.g. pathnames, hostnames). It can not handle arbitrarily ordered data (e.g. query strings, URL fragments, JSON, etc).
4949

5050
### Parameters
5151

52-
The path argument is used to define parameters and populate the list of keys.
52+
The path argument is used to define parameters and populate the list of tokens.
5353

5454
#### Named Parameters
5555

5656
Named parameters are defined by prefixing a colon to the parameter name (`:foo`). By default, the parameter will match until the next prefix (e.g. `[^/]+`).
5757

5858
```go
5959
regexp, err := pathToRegexp.PathToRegexp("/:foo/:bar", nil, nil)
60-
// keys: [
60+
// tokens: [
6161
// {name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"},
6262
// {name:"bar", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"}
6363
// ]
@@ -80,7 +80,7 @@ Parameters can be suffixed with a question mark (`?`) to make the parameter opti
8080

8181
```go
8282
regexp, err := pathToRegexp.PathToRegexp("/:foo/:bar?", nil, nil)
83-
// keys: [
83+
// tokens: [
8484
// {name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"},
8585
// {name:"bar", prefix:"/", delimiter:"/", optional:true, repeat:false, pattern:"[^\\/]+?"}
8686
// ]
@@ -108,7 +108,7 @@ Parameters can be suffixed with an asterisk (`*`) to denote a zero or more param
108108

109109
```go
110110
regexp, err := pathToRegexp.PathToRegexp("/:foo*", nil, nil)
111-
// keys: [{name:"foo", prefix:"/", delimiter:"/", optional:true, repeat:true, pattern:"[^\\/]+?"}]
111+
// tokens: [{name:"foo", prefix:"/", delimiter:"/", optional:true, repeat:true, pattern:"[^\\/]+?"}]
112112

113113
match, err := regexp.FindStringMatch("/")
114114
for _, g := range match.Groups() {
@@ -131,7 +131,7 @@ Parameters can be suffixed with a plus sign (`+`) to denote a one or more parame
131131

132132
```go
133133
regexp, err := pathToRegexp.PathToRegexp("/:foo+", nil, nil)
134-
// keys: [{name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:true, pattern:"[^\\/]+?"}]
134+
// tokens: [{name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:true, pattern:"[^\\/]+?"}]
135135

136136
match, err := regexp.FindStringMatch("/")
137137
fmt.Println(match)
@@ -151,7 +151,7 @@ It is possible to write an unnamed parameter that only consists of a matching gr
151151

152152
```go
153153
regexp, err := pathToRegexp.PathToRegexp("/:foo/(.*)", nil, nil)
154-
// keys: [
154+
// tokens: [
155155
// {name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"},
156156
// {name:0, prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:".*"}
157157
// ]
@@ -170,7 +170,7 @@ All parameters can have a custom regexp, which overrides the default match (`[^/
170170

171171
```go
172172
regexpNumbers, err := pathToRegexp.PathToRegexp("/icon-:foo(\\d+).png", nil, nil)
173-
// keys: {name:"foo", prefix:"-", delimiter:"-", optional:false, repeat:false, pattern:"\\d+"}
173+
// tokens: {name:"foo", prefix:"-", delimiter:"-", optional:false, repeat:false, pattern:"\\d+"}
174174

175175
match, err := regexpNumbers.FindStringMatch("/icon-123.png")
176176
for _, g := range match.Groups() {
@@ -183,7 +183,7 @@ fmt.Println(match)
183183
//=> nil
184184

185185
regexpWord, err := pathToRegexp.PathToRegexp("/(user|u)", nil, nil)
186-
// keys: {name:0, prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"user|u"}
186+
// tokens: {name:0, prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"user|u"}
187187

188188
match, err = regexpWord.FindStringMatch("/u")
189189
for _, g := range match.Groups() {
@@ -200,7 +200,7 @@ fmt.Println(match)
200200

201201
### Parse
202202

203-
The parse function is exposed via `pathToRegexp.Parse`. This will return a slice of strings and keys.
203+
The parse function is exposed via `pathToRegexp.Parse`. This will return a slice of strings and tokens.
204204

205205
```go
206206
tokens := pathToRegexp.Parse("/route/:foo/(.*)", nil)
@@ -209,10 +209,10 @@ fmt.Printf("%#v\n", tokens[0])
209209
//=> "/route"
210210

211211
fmt.Printf("%#v\n", tokens[1])
212-
//=> pathToRegexp.Key{name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"}
212+
//=> pathToRegexp.Token{name:"foo", prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:"[^\\/]+?"}
213213

214214
fmt.Printf("%#v\n", tokens[2])
215-
//=> pathToRegexp.Key{name:0, prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:".*"}
215+
//=> pathToRegexp.Token{name:0, prefix:"/", delimiter:"/", optional:false, repeat:false, pattern:".*"}
216216
```
217217

218218
**Note:** This method only works with strings.

path_to_regexp.go

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a MIT style
33
// license that can be found in the LICENSE file.
44

5-
package path_to_regexp
5+
package pathtoregexp
66

77
import (
88
"errors"
@@ -16,7 +16,9 @@ import (
1616
"github.com/dlclark/regexp2"
1717
)
1818

19-
type Key struct {
19+
// Token is parsed from path. For example, using `/user/:id`, `tokens` will
20+
// contain `[{name:'id', delimiter:'/', optional:false, repeat:false}]`
21+
type Token struct {
2022
// The name of the token (string for named or number for index)
2123
name interface{}
2224

@@ -36,6 +38,7 @@ type Key struct {
3638
pattern string
3739
}
3840

41+
// Options contains some optional configs
3942
type Options struct {
4043
// When true the regexp will be case sensitive. (default: false)
4144
sensitive bool
@@ -64,18 +67,18 @@ type Options struct {
6467
encode func(uri string, token interface{}) string
6568
}
6669

67-
// Default configs.
70+
// DefaultDelimiter is the default delimiter of path.
6871
const DefaultDelimiter = "/"
6972

70-
// The main path matching regexp utility.
73+
// PathRegexp is the main path matching regexp utility.
7174
var PathRegexp = regexp2.MustCompile(strings.Join([]string{
7275
"(\\\\.)",
7376
"(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?",
7477
}, "|"), regexp2.None)
7578

7679
// Parse a string for the raw tokens.
7780
func Parse(str string, o *Options) []interface{} {
78-
tokens, keyIndex, index, path, pathEscaped := make([]interface{}, 0), 0, 0, "", false
81+
tokens, tokenIndex, index, path, pathEscaped := make([]interface{}, 0), 0, 0, "", false
7982
if o == nil {
8083
o = &Options{}
8184
}
@@ -127,10 +130,10 @@ func Parse(str string, o *Options) []interface{} {
127130
pattern := orString(capture, group)
128131
delimiter := orString(prev, defaultDelimiter)
129132

130-
var keyName interface{} = name
133+
var tokenName interface{} = name
131134
if name == "" {
132-
keyName = keyIndex
133-
keyIndex++
135+
tokenName = tokenIndex
136+
tokenIndex++
134137
}
135138
if pattern != "" {
136139
pattern = escapeGroup(pattern)
@@ -141,8 +144,8 @@ func Parse(str string, o *Options) []interface{} {
141144
}
142145
pattern = "[^" + escapeString(d) + "]+?"
143146
}
144-
tokens = append(tokens, Key{
145-
name: keyName,
147+
tokens = append(tokens, Token{
148+
name: tokenName,
146149
prefix: prev,
147150
delimiter: delimiter,
148151
optional: optional,
@@ -172,7 +175,7 @@ func tokensToFunction(tokens []interface{}, o *Options) (
172175

173176
// Compile all the patterns before compilation.
174177
for i, token := range tokens {
175-
if token, ok := token.(Key); ok {
178+
if token, ok := token.(Token); ok {
176179
m, err := regexp2.Compile("^(?:"+token.pattern+")$", flags(o))
177180
if err != nil {
178181
return nil, err
@@ -199,7 +202,7 @@ func tokensToFunction(tokens []interface{}, o *Options) (
199202
continue
200203
}
201204

202-
if token, ok := token.(Key); ok {
205+
if token, ok := token.(Token); ok {
203206
if data != nil && reflect.TypeOf(data).Kind() == reflect.Map {
204207
data := toMap(data)
205208
value := data[token.name]
@@ -331,9 +334,9 @@ func toSlice(data interface{}) []interface{} {
331334

332335
func toMap(data interface{}) map[interface{}]interface{} {
333336
v, m := reflect.ValueOf(data), make(map[interface{}]interface{})
334-
for _, key := range v.MapKeys() {
335-
value := v.MapIndex(key)
336-
m[key.Interface()] = value.Interface()
337+
for _, k := range v.MapKeys() {
338+
value := v.MapIndex(k)
339+
m[k.Interface()] = value.Interface()
337340
}
338341
return m
339342
}
@@ -372,16 +375,16 @@ func flags(o *Options) regexp2.RegexOptions {
372375
return regexp2.IgnoreCase
373376
}
374377

375-
// Pull out keys from a regexp.
376-
func regexpToRegexp(path *regexp2.Regexp, keys *[]Key) *regexp2.Regexp {
377-
if keys != nil {
378+
// Pull out tokens from a regexp.
379+
func regexpToRegexp(path *regexp2.Regexp, tokens *[]Token) *regexp2.Regexp {
380+
if tokens != nil {
378381
r := regexp2.MustCompile("\\((?!\\?)", regexp2.None)
379382
m, _ := r.FindStringMatch(path.String())
380383
if m != nil && m.GroupCount() > 0 {
381-
newKeys := make([]Key, 0, len(*keys)+m.GroupCount())
382-
newKeys = append(newKeys, *keys...)
384+
newTokens := make([]Token, 0, len(*tokens)+m.GroupCount())
385+
newTokens = append(newTokens, *tokens...)
383386
for i := 0; i < m.GroupCount(); i++ {
384-
newKeys = append(newKeys, Key{
387+
newTokens = append(newTokens, Token{
385388
name: i,
386389
prefix: "",
387390
delimiter: "",
@@ -390,20 +393,20 @@ func regexpToRegexp(path *regexp2.Regexp, keys *[]Key) *regexp2.Regexp {
390393
pattern: "",
391394
})
392395
}
393-
hdr := (*reflect.SliceHeader)(unsafe.Pointer(keys))
394-
*hdr = *(*reflect.SliceHeader)(unsafe.Pointer(&newKeys))
396+
hdr := (*reflect.SliceHeader)(unsafe.Pointer(tokens))
397+
*hdr = *(*reflect.SliceHeader)(unsafe.Pointer(&newTokens))
395398
}
396399
}
397400

398401
return path
399402
}
400403

401404
// Transform an array into a regexp.
402-
func arrayToRegexp(path []interface{}, keys *[]Key, o *Options) (*regexp2.Regexp, error) {
405+
func arrayToRegexp(path []interface{}, tokens *[]Token, o *Options) (*regexp2.Regexp, error) {
403406
var parts []string
404407

405408
for i := 0; i < len(path); i++ {
406-
r, err := PathToRegexp(path[i], keys, o)
409+
r, err := PathToRegexp(path[i], tokens, o)
407410
if err != nil {
408411
return nil, err
409412
}
@@ -414,12 +417,12 @@ func arrayToRegexp(path []interface{}, keys *[]Key, o *Options) (*regexp2.Regexp
414417
}
415418

416419
// Create a path regexp from string input.
417-
func stringToRegexp(path string, keys *[]Key, o *Options) (*regexp2.Regexp, error) {
418-
return tokensToRegExp(Parse(path, o), keys, o)
420+
func stringToRegexp(path string, tokens *[]Token, o *Options) (*regexp2.Regexp, error) {
421+
return tokensToRegExp(Parse(path, o), tokens, o)
419422
}
420423

421424
// Expose a function for taking tokens and returning a RegExp.
422-
func tokensToRegExp(tokens []interface{}, keys *[]Key, o *Options) (*regexp2.Regexp, error) {
425+
func tokensToRegExp(rawTokens []interface{}, tokens *[]Token, o *Options) (*regexp2.Regexp, error) {
423426
if o == nil {
424427
o = &Options{}
425428
}
@@ -456,25 +459,25 @@ func tokensToRegExp(tokens []interface{}, keys *[]Key, o *Options) (*regexp2.Reg
456459
route = "^"
457460
}
458461

459-
var newKeys []Key
460-
if keys != nil {
461-
newKeys = make([]Key, 0, len(*keys)+len(tokens))
462-
newKeys = append(newKeys, *keys...)
462+
var newTokens []Token
463+
if tokens != nil {
464+
newTokens = make([]Token, 0, len(*tokens)+len(rawTokens))
465+
newTokens = append(newTokens, *tokens...)
463466
}
464467

465468
// Iterate over the tokens and create our regexp string.
466-
for _, token := range tokens {
469+
for _, token := range rawTokens {
467470
if str, ok := token.(string); ok {
468471
route += escapeString(str)
469-
} else if token, ok := token.(Key); ok {
472+
} else if token, ok := token.(Token); ok {
470473
capture := token.pattern
471474
if token.repeat {
472475
capture = "(?:" + token.pattern + ")(?:" + escapeString(token.delimiter) +
473476
"(?:" + token.pattern + "))*"
474477
}
475478

476-
if keys != nil {
477-
newKeys = append(newKeys, token)
479+
if tokens != nil {
480+
newTokens = append(newTokens, token)
478481
}
479482

480483
if token.optional {
@@ -489,9 +492,9 @@ func tokensToRegExp(tokens []interface{}, keys *[]Key, o *Options) (*regexp2.Reg
489492
}
490493
}
491494

492-
if keys != nil {
493-
hdr := (*reflect.SliceHeader)(unsafe.Pointer(keys))
494-
*hdr = *(*reflect.SliceHeader)(unsafe.Pointer(&newKeys))
495+
if tokens != nil {
496+
hdr := (*reflect.SliceHeader)(unsafe.Pointer(tokens))
497+
*hdr = *(*reflect.SliceHeader)(unsafe.Pointer(&newTokens))
495498
}
496499

497500
if end {
@@ -506,10 +509,10 @@ func tokensToRegExp(tokens []interface{}, keys *[]Key, o *Options) (*regexp2.Reg
506509
route += s
507510
} else {
508511
isEndDelimited := false
509-
if len(tokens) == 0 {
512+
if len(rawTokens) == 0 {
510513
isEndDelimited = true
511514
} else {
512-
endToken := tokens[len(tokens)-1]
515+
endToken := rawTokens[len(rawTokens)-1]
513516
if endToken == nil {
514517
isEndDelimited = true
515518
} else if str, ok := endToken.(string); ok {
@@ -528,23 +531,21 @@ func tokensToRegExp(tokens []interface{}, keys *[]Key, o *Options) (*regexp2.Reg
528531
return regexp2.Compile(route, flags(o))
529532
}
530533

531-
// Normalize the given path string, returning a regular expression.
532-
// An empty array can be passed in for the keys, which will hold the
533-
// placeholder key descriptions. For example, using `/user/:id`, `keys` will
534-
// contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
535-
func PathToRegexp(path interface{}, keys *[]Key, options *Options) (*regexp2.Regexp, error) {
534+
// PathToRegexp normalizes the given path string, returning a regular expression.
535+
// An empty array can be passed in for the tokens, which will hold the
536+
// placeholder token descriptions. For example, using `/user/:id`, `tokens` will
537+
// contain `[{name: 'id', delimiter: '/', optional: false, repeat: false}]`.
538+
func PathToRegexp(path interface{}, tokens *[]Token, options *Options) (*regexp2.Regexp, error) {
536539
switch path := path.(type) {
537540
case *regexp2.Regexp:
538-
return regexpToRegexp(path, keys), nil
539-
case []interface{}:
540-
return arrayToRegexp(path, keys, options)
541+
return regexpToRegexp(path, tokens), nil
541542
case string:
542-
return stringToRegexp(path, keys, options)
543+
return stringToRegexp(path, tokens, options)
543544
}
544545

545546
switch reflect.TypeOf(path).Kind() {
546547
case reflect.Slice, reflect.Array:
547-
return arrayToRegexp(toSlice(path), keys, options)
548+
return arrayToRegexp(toSlice(path), tokens, options)
548549
}
549550

550551
return nil, errors.New(`path should be string, array or slice of strings,

0 commit comments

Comments
 (0)