From 38abfb80edbc42f121841b3d713a97ebbb7d00c1 Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Wed, 17 Feb 2021 14:01:05 +0800 Subject: [PATCH] fix gocyclo warnings (#468) --- core/mapping/unmarshaler.go | 5 +- core/mapping/utils.go | 172 +++++++++++++++++++----------------- core/search/tree.go | 44 +++++---- 3 files changed, 120 insertions(+), 101 deletions(-) diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go index 3b068a92..276b8f50 100644 --- a/core/mapping/unmarshaler.go +++ b/core/mapping/unmarshaler.go @@ -200,7 +200,7 @@ func (u *Unmarshaler) processFieldNotFromString(field reflect.StructField, value case valueKind == reflect.Map && typeKind == reflect.Struct: return u.processFieldStruct(field, value, mapValue, fullName) case valueKind == reflect.String && typeKind == reflect.Slice: - return u.fillSliceFromString(fieldType, value, mapValue, fullName) + return u.fillSliceFromString(fieldType, value, mapValue) case valueKind == reflect.String && derefedFieldType == durationType: return fillDurationValue(fieldType.Kind(), value, mapValue.(string)) default: @@ -464,8 +464,7 @@ func (u *Unmarshaler) fillSlice(fieldType reflect.Type, value reflect.Value, map return nil } -func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect.Value, - mapValue interface{}, fullName string) error { +func (u *Unmarshaler) fillSliceFromString(fieldType reflect.Type, value reflect.Value, mapValue interface{}) error { var slice []interface{} if err := jsonx.UnmarshalFromString(mapValue.(string), &slice); err != nil { return err diff --git a/core/mapping/utils.go b/core/mapping/utils.go index 0ac03167..6685ea93 100644 --- a/core/mapping/utils.go +++ b/core/mapping/utils.go @@ -69,44 +69,7 @@ func Repr(v interface{}) string { val = val.Elem() } - switch vt := val.Interface().(type) { - case bool: - return strconv.FormatBool(vt) - case error: - return vt.Error() - case float32: - return strconv.FormatFloat(float64(vt), 'f', -1, 32) - case float64: - return strconv.FormatFloat(vt, 'f', -1, 64) - case fmt.Stringer: - return vt.String() - case int: - return strconv.Itoa(vt) - case int8: - return strconv.Itoa(int(vt)) - case int16: - return strconv.Itoa(int(vt)) - case int32: - return strconv.Itoa(int(vt)) - case int64: - return strconv.FormatInt(vt, 10) - case string: - return vt - case uint: - return strconv.FormatUint(uint64(vt), 10) - case uint8: - return strconv.FormatUint(uint64(vt), 10) - case uint16: - return strconv.FormatUint(uint64(vt), 10) - case uint32: - return strconv.FormatUint(uint64(vt), 10) - case uint64: - return strconv.FormatUint(vt, 10) - case []byte: - return string(vt) - default: - return fmt.Sprint(val.Interface()) - } + return reprOfValue(val) } func ValidatePtr(v *reflect.Value) error { @@ -163,48 +126,8 @@ func doParseKeyAndOptions(field reflect.StructField, value string) (string, *fie var fieldOpts fieldOptions for _, segment := range options { option := strings.TrimSpace(segment) - switch { - case option == stringOption: - fieldOpts.FromString = true - case strings.HasPrefix(option, optionalOption): - segs := strings.Split(option, equalToken) - switch len(segs) { - case 1: - fieldOpts.Optional = true - case 2: - fieldOpts.Optional = true - fieldOpts.OptionalDep = segs[1] - default: - return "", nil, fmt.Errorf("field %s has wrong optional", field.Name) - } - case option == optionalOption: - fieldOpts.Optional = true - case strings.HasPrefix(option, optionsOption): - segs := strings.Split(option, equalToken) - if len(segs) != 2 { - return "", nil, fmt.Errorf("field %s has wrong options", field.Name) - } - - fieldOpts.Options = strings.Split(segs[1], optionSeparator) - case strings.HasPrefix(option, defaultOption): - segs := strings.Split(option, equalToken) - if len(segs) != 2 { - return "", nil, fmt.Errorf("field %s has wrong default option", field.Name) - } - - fieldOpts.Default = strings.TrimSpace(segs[1]) - case strings.HasPrefix(option, rangeOption): - segs := strings.Split(option, equalToken) - if len(segs) != 2 { - return "", nil, fmt.Errorf("field %s has wrong range", field.Name) - } - - nr, err := parseNumberRange(segs[1]) - if err != nil { - return "", nil, err - } - - fieldOpts.Range = nr + if err := parseOption(&fieldOpts, field.Name, option); err != nil { + return "", nil, err } } @@ -348,6 +271,95 @@ func parseNumberRange(str string) (*numberRange, error) { }, nil } +func parseOption(fieldOpts *fieldOptions, fieldName string, option string) error { + switch { + case option == stringOption: + fieldOpts.FromString = true + case strings.HasPrefix(option, optionalOption): + segs := strings.Split(option, equalToken) + switch len(segs) { + case 1: + fieldOpts.Optional = true + case 2: + fieldOpts.Optional = true + fieldOpts.OptionalDep = segs[1] + default: + return fmt.Errorf("field %s has wrong optional", fieldName) + } + case option == optionalOption: + fieldOpts.Optional = true + case strings.HasPrefix(option, optionsOption): + segs := strings.Split(option, equalToken) + if len(segs) != 2 { + return fmt.Errorf("field %s has wrong options", fieldName) + } + + fieldOpts.Options = strings.Split(segs[1], optionSeparator) + case strings.HasPrefix(option, defaultOption): + segs := strings.Split(option, equalToken) + if len(segs) != 2 { + return fmt.Errorf("field %s has wrong default option", fieldName) + } + + fieldOpts.Default = strings.TrimSpace(segs[1]) + case strings.HasPrefix(option, rangeOption): + segs := strings.Split(option, equalToken) + if len(segs) != 2 { + return fmt.Errorf("field %s has wrong range", fieldName) + } + + nr, err := parseNumberRange(segs[1]) + if err != nil { + return err + } + + fieldOpts.Range = nr + } + + return nil +} + +func reprOfValue(val reflect.Value) string { + switch vt := val.Interface().(type) { + case bool: + return strconv.FormatBool(vt) + case error: + return vt.Error() + case float32: + return strconv.FormatFloat(float64(vt), 'f', -1, 32) + case float64: + return strconv.FormatFloat(vt, 'f', -1, 64) + case fmt.Stringer: + return vt.String() + case int: + return strconv.Itoa(vt) + case int8: + return strconv.Itoa(int(vt)) + case int16: + return strconv.Itoa(int(vt)) + case int32: + return strconv.Itoa(int(vt)) + case int64: + return strconv.FormatInt(vt, 10) + case string: + return vt + case uint: + return strconv.FormatUint(uint64(vt), 10) + case uint8: + return strconv.FormatUint(uint64(vt), 10) + case uint16: + return strconv.FormatUint(uint64(vt), 10) + case uint32: + return strconv.FormatUint(uint64(vt), 10) + case uint64: + return strconv.FormatUint(vt, 10) + case []byte: + return string(vt) + default: + return fmt.Sprint(val.Interface()) + } +} + func setMatchedPrimitiveValue(kind reflect.Kind, value reflect.Value, v interface{}) error { switch kind { case reflect.Bool: diff --git a/core/search/tree.go b/core/search/tree.go index 3779f790..88a76046 100644 --- a/core/search/tree.go +++ b/core/search/tree.go @@ -77,32 +77,40 @@ func (t *Tree) next(n *node, route string, result *Result) bool { for i := range route { if route[i] == slash { token := route[:i] - for _, children := range n.children { - for k, v := range children { - if r := match(k, token); r.found { - if t.next(v, route[i+1:], result) { - if r.named { - addParam(result, r.key, r.value) - } - - return true + return n.forEach(func(k string, v *node) bool { + if r := match(k, token); r.found { + if t.next(v, route[i+1:], result) { + if r.named { + addParam(result, r.key, r.value) } + + return true } } - } - return false + return false + }) } } - for _, children := range n.children { - for k, v := range children { - if r := match(k, route); r.found && v.item != nil { - result.Item = v.item - if r.named { - addParam(result, r.key, r.value) - } + return n.forEach(func(k string, v *node) bool { + if r := match(k, route); r.found && v.item != nil { + result.Item = v.item + if r.named { + addParam(result, r.key, r.value) + } + return true + } + + return false + }) +} + +func (nd *node) forEach(fn func(string, *node) bool) bool { + for _, children := range nd.children { + for k, v := range children { + if fn(k, v) { return true } }