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 }