diff options
Diffstat (limited to 'vendor/github.com/gocarina/gocsv/types.go')
-rw-r--r-- | vendor/github.com/gocarina/gocsv/types.go | 80 |
1 files changed, 41 insertions, 39 deletions
diff --git a/vendor/github.com/gocarina/gocsv/types.go b/vendor/github.com/gocarina/gocsv/types.go index 50d88ce..a5dda89 100644 --- a/vendor/github.com/gocarina/gocsv/types.go +++ b/vendor/github.com/gocarina/gocsv/types.go @@ -6,6 +6,8 @@ import ( "reflect" "strconv" "strings" + + "encoding/json" ) // -------------------------------------------------------------------------- @@ -17,19 +19,17 @@ type TypeMarshaller interface { MarshalCSV() (string, error) } -// Stringer is implemented by any value that has a String method -// This converter is used to convert the value to it string representation -// This converter will be used if your value does not implement TypeMarshaller -type Stringer interface { - String() string -} - // TypeUnmarshaller is implemented by any value that has an UnmarshalCSV method // This converter is used to convert a string to your value representation of that string type TypeUnmarshaller interface { UnmarshalCSV(string) error } +// TypeUnmarshalCSVWithFields can be implemented on whole structs to allow for whole structures to customized internal vs one off fields +type TypeUnmarshalCSVWithFields interface { + UnmarshalCSVWithFields(key, value string) error +} + // NoUnmarshalFuncError is the custom error type to be raised in case there is no unmarshal function defined on type type NoUnmarshalFuncError struct { msg string @@ -41,21 +41,13 @@ func (e NoUnmarshalFuncError) Error() string { // NoMarshalFuncError is the custom error type to be raised in case there is no marshal function defined on type type NoMarshalFuncError struct { - msg string + ty reflect.Type } func (e NoMarshalFuncError) Error() string { - return e.msg + return "No known conversion from " + e.ty.String() + " to string, " + e.ty.String() + " does not implement TypeMarshaller nor Stringer" } -var ( - stringerType = reflect.TypeOf((*Stringer)(nil)).Elem() - marshallerType = reflect.TypeOf((*TypeMarshaller)(nil)).Elem() - unMarshallerType = reflect.TypeOf((*TypeUnmarshaller)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - textUnMarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() -) - // -------------------------------------------------------------------------- // Conversion helpers @@ -89,12 +81,12 @@ func toBool(in interface{}) (bool, error) { switch inValue.Kind() { case reflect.String: s := inValue.String() - switch s { - case "yes": + s = strings.TrimSpace(s) + if strings.EqualFold(s, "yes") { return true, nil - case "no", "": + } else if strings.EqualFold(s, "no") || s == "" { return false, nil - default: + } else { return strconv.ParseBool(s) } case reflect.Bool: @@ -130,7 +122,8 @@ func toInt(in interface{}) (int64, error) { if s == "" { return 0, nil } - return strconv.ParseInt(s, 0, 64) + out := strings.SplitN(s, ".", 2) + return strconv.ParseInt(out[0], 0, 64) case reflect.Bool: if inValue.Bool() { return 1, nil @@ -285,6 +278,11 @@ func setField(field reflect.Value, value string, omitEmpty bool) error { return err } field.SetFloat(f) + case reflect.Slice, reflect.Struct: + err := json.Unmarshal([]byte(value), field.Addr().Interface()) + if err != nil { + return err + } default: return err } @@ -297,32 +295,28 @@ func setField(field reflect.Value, value string, omitEmpty bool) error { func getFieldAsString(field reflect.Value) (str string, err error) { switch field.Kind() { - case reflect.Interface: - case reflect.Ptr: + case reflect.Interface, reflect.Ptr: if field.IsNil() { return "", nil } return getFieldAsString(field.Elem()) + case reflect.String: + return field.String(), nil default: // Check if field is go native type switch field.Interface().(type) { case string: return field.String(), nil case bool: - str, err = toString(field.Bool()) - if err != nil { - return str, err + if field.Bool() { + return "true", nil + } else { + return "false", nil } case int, int8, int16, int32, int64: - str, err = toString(field.Int()) - if err != nil { - return str, err - } + return fmt.Sprintf("%v", field.Int()), nil case uint, uint8, uint16, uint32, uint64: - str, err = toString(field.Uint()) - if err != nil { - return str, err - } + return fmt.Sprintf("%v", field.Uint()), nil case float32: str, err = toString(float32(field.Float())) if err != nil { @@ -381,6 +375,14 @@ func getFieldAsString(field reflect.Value) (str string, err error) { // -------------------------------------------------------------------------- // Un/serializations helpers +func canMarshal(t reflect.Type) bool { + // unless it implements marshalText or marshalCSV. Structs that implement this + // should result in one value and not have their fields exposed + _, canMarshalText := t.MethodByName("MarshalText") + _, canMarshalCSV := t.MethodByName("MarshalCSV") + return canMarshalCSV || canMarshalText +} + func unmarshall(field reflect.Value, value string) error { dupField := field unMarshallIt := func(finalField reflect.Value) error { @@ -435,13 +437,13 @@ func marshall(field reflect.Value) (value string, err error) { } // Otherwise try to use Stringer - fieldStringer, ok := fieldIface.(Stringer) + fieldStringer, ok := fieldIface.(fmt.Stringer) if ok { return fieldStringer.String(), nil } } - return value, NoMarshalFuncError{"No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implement TypeMarshaller nor Stringer"} + return value, NoMarshalFuncError{field.Type()} } for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr { if dupField.IsNil() { @@ -450,7 +452,7 @@ func marshall(field reflect.Value) (value string, err error) { dupField = dupField.Elem() } if dupField.CanAddr() { - return marshallIt(dupField.Addr()) + dupField = dupField.Addr() } - return value, NoMarshalFuncError{"No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implement TypeMarshaller nor Stringer"} + return marshallIt(dupField) } |