made it so .FindAndLoad() can load to a *[]string too.
parent
cd58524dc0
commit
4e99dd5057
|
@ -14,7 +14,13 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func (pattern *Pattern) FindAndLoad(path string, strct interface{}) (bool, error) {
|
// FindAndLoad compares ‘path’ against its (compiled) pattern template; if it matches
|
||||||
|
// it loads the matches into ‘dest’, and then returns true.
|
||||||
|
//
|
||||||
|
// ‘dest’ can be a pointer struct, or a pointer to a []string.
|
||||||
|
//
|
||||||
|
// Find may set some, or all of the items or fields in ‘dest’ even if it returns false, and even if it returns an error.
|
||||||
|
func (pattern *Pattern) FindAndLoad(path string, dest interface{}) (bool, error) {
|
||||||
if nil == pattern {
|
if nil == pattern {
|
||||||
return false, errNilReceiver
|
return false, errNilReceiver
|
||||||
}
|
}
|
||||||
|
@ -39,12 +45,56 @@ func (pattern *Pattern) FindAndLoad(path string, strct interface{}) (bool, error
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
reflectedValue := reflect.ValueOf(strct)
|
reflectedValue := reflect.ValueOf(dest)
|
||||||
if reflect.Ptr != reflectedValue.Kind() {
|
if reflect.Ptr != reflectedValue.Kind() {
|
||||||
|
//@TODO: change error
|
||||||
return doesNotMatter, errExpectedAPointerToAStruct
|
return doesNotMatter, errExpectedAPointerToAStruct
|
||||||
}
|
}
|
||||||
|
|
||||||
reflectedValueElem := reflectedValue.Elem()
|
reflectedValueElem := reflectedValue.Elem()
|
||||||
|
switch reflectedValueElem.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
var a []string = make([]string, len(args))
|
||||||
|
for i, arg := range args {
|
||||||
|
a[i] = *(arg.(*string))
|
||||||
|
}
|
||||||
|
|
||||||
|
return loadSlice(dest, a...)
|
||||||
|
case reflect.Struct:
|
||||||
|
return pattern.loadStruct(reflectedValueElem, args)
|
||||||
|
default:
|
||||||
|
//@TODO: change error
|
||||||
|
return doesNotMatter, errExpectedAPointerToAStruct
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadSlice(dest interface{}, matches ...string) (bool, error) {
|
||||||
|
if nil == dest {
|
||||||
|
return false, errNilTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
target, casted := dest.(*[]string)
|
||||||
|
if !casted {
|
||||||
|
//@TODO: CHANGE ERROR! ============================
|
||||||
|
return false, errExpectedAPointerToAStruct
|
||||||
|
}
|
||||||
|
if nil == target {
|
||||||
|
return false, errNilTarget
|
||||||
|
}
|
||||||
|
|
||||||
|
*target = (*target)[:0]
|
||||||
|
for _, match := range matches {
|
||||||
|
*target = append(*target, match)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pattern *Pattern) loadStruct(reflectedValueElem reflect.Value, args []interface{}) (bool, error) {
|
||||||
|
if nil == pattern {
|
||||||
|
return false, errNilReceiver
|
||||||
|
}
|
||||||
|
|
||||||
if reflect.Struct != reflectedValueElem.Kind() {
|
if reflect.Struct != reflectedValueElem.Kind() {
|
||||||
return doesNotMatter, errExpectedAPointerToAStruct
|
return doesNotMatter, errExpectedAPointerToAStruct
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,13 @@ package pathmatch
|
||||||
import (
|
import (
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
|
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func TestFindAndLoad(t *testing.T) {
|
func TestFindAndLoadStrucs(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct{
|
tests := []struct{
|
||||||
Pattern *Pattern
|
Pattern *Pattern
|
||||||
|
@ -166,3 +168,73 @@ func TestFindAndLoad(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFindAndLoadStrings(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct{
|
||||||
|
Pattern *Pattern
|
||||||
|
Path string
|
||||||
|
Expected []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Pattern: MustCompile("/user/{sessionKey}"),
|
||||||
|
Path: "/user/76M6.mXQfgiGSC_YJ5uXSnWUmELbe8OgOm5n.iZ98Ij",
|
||||||
|
Expected: []string{"76M6.mXQfgiGSC_YJ5uXSnWUmELbe8OgOm5n.iZ98Ij"},
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Pattern: MustCompile("/user/{sessionKey}/vehicle/{vehicleIdcode}/"),
|
||||||
|
Path: "/user/76M6.mXQfgiGSC_YJ5uXSnWUmELbe8OgOm5n.iZ98Ij/vehicle/DEFAULT/",
|
||||||
|
Expected: []string{
|
||||||
|
"76M6.mXQfgiGSC_YJ5uXSnWUmELbe8OgOm5n.iZ98Ij",
|
||||||
|
"DEFAULT",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
Pattern: MustCompile("/{this}/{that}/{these}/{those}"),
|
||||||
|
Path: "/apple/banana/cherry/grape",
|
||||||
|
Expected: []string{
|
||||||
|
"apple",
|
||||||
|
"banana",
|
||||||
|
"cherry",
|
||||||
|
"grape",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for testNumber, test := range tests {
|
||||||
|
|
||||||
|
var actual []string
|
||||||
|
|
||||||
|
matched, err := test.Pattern.FindAndLoad(test.Path, &actual)
|
||||||
|
if nil != err {
|
||||||
|
t.Errorf("For test #%d, did not expect an error, but actually got one: (%T) %q", testNumber, err, err)
|
||||||
|
t.Logf("\tPATTERN: %q", test.Pattern)
|
||||||
|
t.Logf("\tPATH: %q", test.Path)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("For test #%d, expected a match, but it didn't.", testNumber)
|
||||||
|
t.Logf("\tPATTERN: %q", test.Pattern)
|
||||||
|
t.Logf("\tPATH: %q", test.Path)
|
||||||
|
t.Log("\t--")
|
||||||
|
t.Logf("\tMATCHED: %t", matched)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected := test.Expected; !reflect.DeepEqual(expected, actual) {
|
||||||
|
t.Errorf("For test #%d, did not get what was expected.", testNumber)
|
||||||
|
t.Logf("\tPATTERN: %q", test.Pattern)
|
||||||
|
t.Logf("\tPATH: %q", test.Path)
|
||||||
|
t.Log("\t--")
|
||||||
|
t.Logf("\tEXPECTED: %#v", expected)
|
||||||
|
t.Logf("\tACTUAL: %#v", actual)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue