mutex
parent
afd2d359db
commit
2220e2822d
|
@ -1,24 +1,20 @@
|
||||||
package pathmatch
|
package pathmatch
|
||||||
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultFieldTagName = "match"
|
defaultFieldTagName = "match"
|
||||||
wildcardBit = "{}"
|
wildcardBit = "{}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errMissingEndingRightBraceToMatchBeginningLeftBrace = newPatternSyntaxError(`Missing ending "}" (to match beginning "{").`)
|
errMissingEndingRightBraceToMatchBeginningLeftBrace = newPatternSyntaxError(`Missing ending "}" (to match beginning "{").`)
|
||||||
errSlashInsideOfBraces = newPatternSyntaxError(`"/" inside of "{...}".`)
|
errSlashInsideOfBraces = newPatternSyntaxError(`"/" inside of "{...}".`)
|
||||||
errLeftBraceInsideOfBraces = newPatternSyntaxError(`"{" inside of "{...}".`)
|
errLeftBraceInsideOfBraces = newPatternSyntaxError(`"{" inside of "{...}".`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// Compile takes an uncompiled pattern, in the form of a Go string (ex: "/users/{userId}/vehicles/{vehicleId}"),
|
// Compile takes an uncompiled pattern, in the form of a Go string (ex: "/users/{userId}/vehicles/{vehicleId}"),
|
||||||
// and returns a compiled pattern.
|
// and returns a compiled pattern.
|
||||||
//
|
//
|
||||||
|
@ -66,7 +62,10 @@ func CompileTo(target *Pattern, uncompiledPattern string) error {
|
||||||
return errNilTarget
|
return errNilTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
newPattern(target, defaultFieldTagName)
|
target.mutex.Lock()
|
||||||
|
defer target.mutex.Unlock()
|
||||||
|
|
||||||
|
target.init(defaultFieldTagName)
|
||||||
|
|
||||||
s := uncompiledPattern
|
s := uncompiledPattern
|
||||||
for {
|
for {
|
||||||
|
|
|
@ -5,5 +5,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
errNilReceiver = errors.New("pathmatch: Nil Receiver")
|
||||||
errNilTarget = errors.New("pathmatch: Nil Target")
|
errNilTarget = errors.New("pathmatch: Nil Target")
|
||||||
)
|
)
|
||||||
|
|
40
pattern.go
40
pattern.go
|
@ -1,7 +1,7 @@
|
||||||
package pathmatch
|
package pathmatch
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pattern represents a compiled pattern. It is what is returned
|
// Pattern represents a compiled pattern. It is what is returned
|
||||||
|
@ -31,46 +31,20 @@ import (
|
||||||
// fmt.Println("Did not match.")
|
// fmt.Println("Did not match.")
|
||||||
// }
|
// }
|
||||||
type Pattern struct {
|
type Pattern struct {
|
||||||
|
mutex sync.RWMutex
|
||||||
bits []string
|
bits []string
|
||||||
names []string
|
names []string
|
||||||
namesSet map[string]struct{}
|
namesSet map[string]struct{}
|
||||||
fieldTagName string
|
fieldTagName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPattern(target *Pattern, fieldTagName string) error {
|
func (pattern *Pattern) MatchNames() []string {
|
||||||
if nil == target {
|
if nil == pattern {
|
||||||
return errNilTarget
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
bits := []string{}
|
pattern.mutex.RLock()
|
||||||
names := []string{}
|
defer pattern.mutex.RUnlock()
|
||||||
namesSet := map[string]struct{}{}
|
|
||||||
|
|
||||||
target.bits = bits
|
|
||||||
target.names = names
|
|
||||||
target.namesSet = namesSet
|
|
||||||
target.fieldTagName = fieldTagName
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (pattern *Pattern) MatchNames() []string {
|
|
||||||
|
|
||||||
return pattern.names
|
return pattern.names
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pattern *Pattern) Glob() string {
|
|
||||||
//@TODO: This shouldn't be executed every time!
|
|
||||||
|
|
||||||
var buffer bytes.Buffer
|
|
||||||
|
|
||||||
for _, bit := range pattern.bits {
|
|
||||||
if wildcardBit == bit {
|
|
||||||
buffer.WriteRune('*')
|
|
||||||
} else {
|
|
||||||
buffer.WriteString(bit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer.String()
|
|
||||||
}
|
|
||||||
|
|
|
@ -13,6 +13,12 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (pattern *Pattern) Find(path string, args ...interface{}) (bool, error) {
|
func (pattern *Pattern) Find(path string, args ...interface{}) (bool, error) {
|
||||||
|
if nil == pattern {
|
||||||
|
return false, errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern.mutex.RLock()
|
||||||
|
defer pattern.mutex.RUnlock()
|
||||||
|
|
||||||
s := path
|
s := path
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
package pathmatch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (pattern *Pattern) Glob() string {
|
||||||
|
if nil == pattern {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern.mutex.RLock()
|
||||||
|
defer pattern.mutex.RUnlock()
|
||||||
|
|
||||||
|
//@TODO: This shouldn't be executed every time!
|
||||||
|
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
|
||||||
|
for _, bit := range pattern.bits {
|
||||||
|
if wildcardBit == bit {
|
||||||
|
buffer.WriteRune('*')
|
||||||
|
} else {
|
||||||
|
buffer.WriteString(bit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.String()
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package pathmatch
|
||||||
|
|
||||||
|
func (receiver *Pattern) init(fieldTagName string) {
|
||||||
|
if nil == receiver {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bits := []string{}
|
||||||
|
names := []string{}
|
||||||
|
namesSet := map[string]struct{}{}
|
||||||
|
|
||||||
|
receiver.bits = bits
|
||||||
|
receiver.names = names
|
||||||
|
receiver.namesSet = namesSet
|
||||||
|
receiver.fieldTagName = fieldTagName
|
||||||
|
}
|
|
@ -15,6 +15,12 @@ var (
|
||||||
|
|
||||||
|
|
||||||
func (pattern *Pattern) FindAndLoad(path string, strct interface{}) (bool, error) {
|
func (pattern *Pattern) FindAndLoad(path string, strct interface{}) (bool, error) {
|
||||||
|
if nil == pattern {
|
||||||
|
return false, errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern.mutex.RLock()
|
||||||
|
defer pattern.mutex.RUnlock()
|
||||||
|
|
||||||
//@TODO: Is it a good idea to be dynamically creating this?
|
//@TODO: Is it a good idea to be dynamically creating this?
|
||||||
//@TODO: Also, can the struct fields be put in here directly instead?
|
//@TODO: Also, can the struct fields be put in here directly instead?
|
||||||
|
|
Loading…
Reference in New Issue