108 lines
2.4 KiB
Go
108 lines
2.4 KiB
Go
package router
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func bindObj(obj interface{}, kvmap map[string]string, sTag string) error {
|
|
var err error
|
|
vElem := reflect.ValueOf(obj).Elem()
|
|
sElem := reflect.TypeOf(obj).Elem()
|
|
for i := 0; i < vElem.NumField(); i++ {
|
|
vField := vElem.Field(i)
|
|
tag := sElem.Field(i).Tag.Get(sTag)
|
|
if tag != "" {
|
|
sVal, exists := kvmap[tag]
|
|
if exists {
|
|
switch vField.Kind() {
|
|
case reflect.String:
|
|
vField.SetString(sVal)
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
iVal, err := strconv.ParseInt(sVal, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
vField.SetInt(iVal)
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
iVal, err := strconv.ParseUint(sVal, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
vField.SetUint(iVal)
|
|
case reflect.Bool:
|
|
bVal, err := strconv.ParseBool(sVal)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
vField.SetBool(bVal)
|
|
case reflect.Float32, reflect.Float64:
|
|
fVal, err := strconv.ParseFloat(sVal, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
vField.SetFloat(fVal)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
const (
|
|
defaultItemPattern = `(?P<%s>[a-zA-Z0-9_][\-\.a-zA-Z0-9_=:~]+)`
|
|
itemRegexepPattern = `(?P<%s>%s)`
|
|
)
|
|
|
|
func pathComp(path string) string {
|
|
convFunc := func(item []byte) []byte {
|
|
itemData := strings.Split(string(item), ":")
|
|
var convItem string
|
|
if len(itemData) > 1 {
|
|
convItem = fmt.Sprintf(itemRegexepPattern, itemData[0], itemData[1])
|
|
} else {
|
|
convItem = fmt.Sprintf(defaultItemPattern, string(item))
|
|
}
|
|
return []byte(convItem)
|
|
}
|
|
return string(replaceTemplates([]byte(path), convFunc))
|
|
}
|
|
|
|
func replaceTemplates(path []byte, convFunc func([]byte) []byte) []byte {
|
|
convPath := make([]byte, 0)
|
|
tmpBuf := make([]byte, 0)
|
|
var lsPos int
|
|
lbFound := false
|
|
var rsPos int
|
|
for i := 0; i < len(path); i++ {
|
|
switch {
|
|
case path[i] == '{':
|
|
lsPos = i + 1
|
|
if lbFound {
|
|
convPath = append(convPath, tmpBuf...)
|
|
}
|
|
lbFound = true
|
|
tmpBuf = make([]byte, 0)
|
|
tmpBuf = append(tmpBuf, path[i])
|
|
case path[i] == '}':
|
|
rsPos = i
|
|
if lbFound {
|
|
subst := convFunc(path[lsPos:rsPos])
|
|
convPath = append(convPath, subst...)
|
|
lbFound = false
|
|
} else {
|
|
convPath = append(convPath, path[i])
|
|
}
|
|
default:
|
|
if !lbFound {
|
|
convPath = append(convPath, path[i])
|
|
} else {
|
|
tmpBuf = append(tmpBuf, path[i])
|
|
}
|
|
}
|
|
}
|
|
return convPath
|
|
}
|