From d21f39eeebd3586e7faf4d83c7a8e12b6e04c82e Mon Sep 17 00:00:00 2001 From: Victor Häggqvist Date: Tue, 21 Apr 2020 09:34:44 +0200 Subject: replace ini --- vendor/github.com/gocarina/gocsv/reflect.go | 57 +++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 12 deletions(-) (limited to 'vendor/github.com/gocarina/gocsv/reflect.go') diff --git a/vendor/github.com/gocarina/gocsv/reflect.go b/vendor/github.com/gocarina/gocsv/reflect.go index 9217e30..dfc63b3 100644 --- a/vendor/github.com/gocarina/gocsv/reflect.go +++ b/vendor/github.com/gocarina/gocsv/reflect.go @@ -35,19 +35,21 @@ func (f fieldInfo) matchesKey(key string) bool { return false } +var structInfoCache sync.Map var structMap = make(map[reflect.Type]*structInfo) var structMapMutex sync.RWMutex func getStructInfo(rType reflect.Type) *structInfo { - structMapMutex.RLock() - stInfo, ok := structMap[rType] - structMapMutex.RUnlock() + stInfo, ok := structInfoCache.Load(rType) if ok { - return stInfo + return stInfo.(*structInfo) } + fieldsList := getFieldInfos(rType, []int{}) stInfo = &structInfo{fieldsList} - return stInfo + structInfoCache.Store(rType, stInfo) + + return stInfo.(*structInfo) } func getFieldInfos(rType reflect.Type, parentIndexChain []int) []fieldInfo { @@ -58,19 +60,40 @@ func getFieldInfos(rType reflect.Type, parentIndexChain []int) []fieldInfo { if field.PkgPath != "" { continue } - indexChain := append(parentIndexChain, i) - // if the field is an embedded struct, create a fieldInfo for each of its fields - if field.Anonymous && field.Type.Kind() == reflect.Struct { - fieldsList = append(fieldsList, getFieldInfos(field.Type, indexChain)...) + + var cpy = make([]int, len(parentIndexChain)) + copy(cpy, parentIndexChain) + indexChain := append(cpy, i) + + // if the field is a pointer to a struct, follow the pointer then create fieldinfo for each field + if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct { + // unless it implements marshalText or marshalCSV. Structs that implement this + // should result in one value and not have their fields exposed + if !(canMarshal(field.Type.Elem())) { + fieldsList = append(fieldsList, getFieldInfos(field.Type.Elem(), indexChain)...) + } + } + // if the field is a struct, create a fieldInfo for each of its fields + if field.Type.Kind() == reflect.Struct { + // unless it implements marshalText or marshalCSV. Structs that implement this + // should result in one value and not have their fields exposed + if !(canMarshal(field.Type)) { + fieldsList = append(fieldsList, getFieldInfos(field.Type, indexChain)...) + } + } + + // if the field is an embedded struct, ignore the csv tag + if field.Anonymous { continue } + fieldInfo := fieldInfo{IndexChain: indexChain} - fieldTag := field.Tag.Get("csv") + fieldTag := field.Tag.Get(TagName) fieldTags := strings.Split(fieldTag, TagSeparator) filteredTags := []string{} for _, fieldTagEntry := range fieldTags { if fieldTagEntry != "omitempty" { - filteredTags = append(filteredTags, fieldTagEntry) + filteredTags = append(filteredTags, normalizeName(fieldTagEntry)) } else { fieldInfo.omitEmpty = true } @@ -81,7 +104,7 @@ func getFieldInfos(rType reflect.Type, parentIndexChain []int) []fieldInfo { } else if len(filteredTags) > 0 && filteredTags[0] != "" { fieldInfo.keys = filteredTags } else { - fieldInfo.keys = []string{field.Name} + fieldInfo.keys = []string{normalizeName(field.Name)} } fieldsList = append(fieldsList, fieldInfo) } @@ -105,3 +128,13 @@ func getConcreteReflectValueAndType(in interface{}) (reflect.Value, reflect.Type } return value, value.Type() } + +var errorInterface = reflect.TypeOf((*error)(nil)).Elem() + +func isErrorType(outType reflect.Type) bool { + if outType.Kind() != reflect.Interface { + return false + } + + return outType.Implements(errorInterface) +} -- cgit v1.2.3