refactoring pathmatch.Compile()

master
Charles Iliya Krempeaux 2019-06-21 12:49:06 -07:00
parent eb4a553ef2
commit e4db362f72
4 changed files with 32 additions and 21 deletions

View File

@ -33,22 +33,23 @@ var (
// fmt.Printf("ERROR Compiling: %v\n", err) // fmt.Printf("ERROR Compiling: %v\n", err)
// return // return
// } // }
func Compile(uncompiledPattern string) (*Pattern, error) { func Compile(target *Pattern, uncompiledPattern string) error {
if nil == target {
return errNilTarget
}
var pattern Pattern newPattern(target, defaultFieldTagName)
newPattern(&pattern, defaultFieldTagName)
s := uncompiledPattern s := uncompiledPattern
for { for {
index := strings.IndexRune(s, '{') index := strings.IndexRune(s, '{')
if -1 == index { if -1 == index {
pattern.bits = append(pattern.bits, s) target.bits = append(target.bits, s)
break break
} }
bit := s[:index] bit := s[:index]
if "" != bit { // This is to deal with the case where a {???} is right at the beginning of the uncompiledPattern. if "" != bit { // This is to deal with the case where a {???} is right at the beginning of the uncompiledPattern.
pattern.bits = append(pattern.bits, bit) target.bits = append(target.bits, bit)
} }
s = s[1+index:] s = s[1+index:]
if "" == s { if "" == s {
@ -57,21 +58,21 @@ func Compile(uncompiledPattern string) (*Pattern, error) {
index = strings.IndexRune(s, '}') index = strings.IndexRune(s, '}')
if -1 == index { if -1 == index {
return nil, errMissingEndingRightBraceToMatchBeginningLeftBrace return errMissingEndingRightBraceToMatchBeginningLeftBrace
} }
// There should not be a slash ("/") before the ending brace ("}"). // There should not be a slash ("/") before the ending brace ("}").
// If there is, it is a syntax error. // If there is, it is a syntax error.
slashIndex := strings.IndexRune(s, '/') slashIndex := strings.IndexRune(s, '/')
if -1 != slashIndex && slashIndex <= index { if -1 != slashIndex && slashIndex <= index {
return nil, errSlashInsideOfBraces return errSlashInsideOfBraces
} }
// There should not be another beginning brace ("{") before the ending brace ("}"). // There should not be another beginning brace ("{") before the ending brace ("}").
// If there is, it is a syntax error. // If there is, it is a syntax error.
anotherLeftBraceIndex := strings.IndexRune(s, '{') anotherLeftBraceIndex := strings.IndexRune(s, '{')
if -1 != anotherLeftBraceIndex && anotherLeftBraceIndex <= index { if -1 != anotherLeftBraceIndex && anotherLeftBraceIndex <= index {
return nil, errLeftBraceInsideOfBraces return errLeftBraceInsideOfBraces
} }
@ -79,14 +80,14 @@ func Compile(uncompiledPattern string) (*Pattern, error) {
// Match names should be unique, within a pattern. // Match names should be unique, within a pattern.
if _, ok := pattern.namesSet[bit]; ok { if _, ok := target.namesSet[bit]; ok {
return nil, newPatternSyntaxError("Duplicate match name: %q.", bit) return newPatternSyntaxError("Duplicate match name: %q.", bit)
} }
pattern.names = append(pattern.names, bit) target.names = append(target.names, bit)
pattern.namesSet[bit] = struct{}{} target.namesSet[bit] = struct{}{}
pattern.bits = append(pattern.bits, wildcardBit) target.bits = append(target.bits, wildcardBit)
s = s[1+index:] s = s[1+index:]
if "" == s { if "" == s {
break break
@ -94,7 +95,7 @@ func Compile(uncompiledPattern string) (*Pattern, error) {
} }
return &pattern, nil return nil
} }
@ -108,9 +109,11 @@ func Compile(uncompiledPattern string) (*Pattern, error) {
// Note that if one recover()s from the panic(), one can use a Go type-switch // Note that if one recover()s from the panic(), one can use a Go type-switch
// to figure out what kind of error it is. // to figure out what kind of error it is.
func MustCompile(uncompiledPattern string) *Pattern { func MustCompile(uncompiledPattern string) *Pattern {
if pattern, err := Compile(uncompiledPattern); nil != err { var pattern Pattern
if err := Compile(&pattern, uncompiledPattern); nil != err {
panic(err) panic(err)
} else { } else {
return pattern return &pattern
} }
} }

View File

@ -454,7 +454,9 @@ func TestCompileAndMatchNames(t *testing.T) {
for testNumber, test := range tests { for testNumber, test := range tests {
actualPattern, err := Compile(test.UncompiledPattern) var actualPattern Pattern
err := Compile(&actualPattern, test.UncompiledPattern)
if nil != err { if nil != err {
t.Errorf("For test #%d, did not expect to receive an error, but actually got one: %v\nPATTERN: %q", testNumber, err, test.UncompiledPattern) t.Errorf("For test #%d, did not expect to receive an error, but actually got one: %v\nPATTERN: %q", testNumber, err, test.UncompiledPattern)
continue continue
@ -547,7 +549,9 @@ func TestCompileFail(t *testing.T) {
for testNumber, test := range tests { for testNumber, test := range tests {
_, err := Compile(test.UncompiledPattern) var pattern Pattern
err := Compile(&pattern, test.UncompiledPattern)
if nil == err { if nil == err {
t.Errorf("For test #%d, expected to receive an error, but actually did not get one: %v\nPATTERN: %q", testNumber, err, test.UncompiledPattern) t.Errorf("For test #%d, expected to receive an error, but actually did not get one: %v\nPATTERN: %q", testNumber, err, test.UncompiledPattern)
continue continue

View File

@ -8,7 +8,9 @@ import (
func ExampleCompile() { func ExampleCompile() {
pattern, err := pathmatch.Compile("/v1/users/{user_id}/contacts/{contact_type}") var pattern pathmatch.Pattern
err := pathmatch.Compile(&pattern, "/v1/users/{user_id}/contacts/{contact_type}")
if nil != err { if nil != err {
fmt.Printf("ERROR: %s\n", err) fmt.Printf("ERROR: %s\n", err)
return return

View File

@ -192,7 +192,9 @@ func TestGlob(t *testing.T) {
for testNumber, test := range tests { for testNumber, test := range tests {
pattern, err := Compile(test.Pattern) var pattern Pattern
err := Compile(&pattern, test.Pattern)
if nil != err { if nil != err {
t.Errorf("For test #%d, did not expected an error, but actually got one: %v", testNumber, err) t.Errorf("For test #%d, did not expected an error, but actually got one: %v", testNumber, err)
continue continue