| 
					
				 | 
			
			
				@@ -0,0 +1,439 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+package gocsv 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+import ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"encoding" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"fmt" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"reflect" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"strconv" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	"strings" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// -------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Conversion interfaces 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// TypeMarshaller is implemented by any value that has a MarshalCSV method 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// This converter is used to convert the value to it string representation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// NoUnmarshalFuncError is the custom error type to be raised in case there is no unmarshal function defined on type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type NoUnmarshalFuncError struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	msg string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e NoUnmarshalFuncError) Error() string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return e.msg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// NoMarshalFuncError is the custom error type to be raised in case there is no marshal function defined on type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+type NoMarshalFuncError struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	msg string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (e NoMarshalFuncError) Error() string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return e.msg 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func toString(in interface{}) (string, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	inValue := reflect.ValueOf(in) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch inValue.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return inValue.String(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		b := inValue.Bool() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if b { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "true", nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return "false", nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return fmt.Sprintf("%v", inValue.Int()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return fmt.Sprintf("%v", inValue.Uint()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Float32: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return strconv.FormatFloat(inValue.Float(), byte('f'), -1, 32), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return strconv.FormatFloat(inValue.Float(), byte('f'), -1, 64), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return "", fmt.Errorf("No known conversion from " + inValue.Type().String() + " to string") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func toBool(in interface{}) (bool, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	inValue := reflect.ValueOf(in) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch inValue.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		s := inValue.String() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		switch s { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "yes": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return true, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case "no", "": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return false, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return strconv.ParseBool(s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return inValue.Bool(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		i := inValue.Int() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if i != 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return true, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		i := inValue.Uint() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if i != 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return true, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Float32, reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		f := inValue.Float() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if f != 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return true, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return false, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return false, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to bool") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func toInt(in interface{}) (int64, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	inValue := reflect.ValueOf(in) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch inValue.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		s := strings.TrimSpace(inValue.String()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if s == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return 0, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return strconv.ParseInt(s, 0, 64) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if inValue.Bool() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return 1, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 0, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return inValue.Int(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return int64(inValue.Uint()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Float32, reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return int64(inValue.Float()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to int") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func toUint(in interface{}) (uint64, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	inValue := reflect.ValueOf(in) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch inValue.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		s := strings.TrimSpace(inValue.String()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if s == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return 0, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// support the float input 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if strings.Contains(s, ".") { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			f, err := strconv.ParseFloat(s, 64) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return 0, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return uint64(f), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return strconv.ParseUint(s, 0, 64) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if inValue.Bool() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return 1, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 0, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return uint64(inValue.Int()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return inValue.Uint(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Float32, reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return uint64(inValue.Float()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to uint") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func toFloat(in interface{}) (float64, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	inValue := reflect.ValueOf(in) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch inValue.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		s := strings.TrimSpace(inValue.String()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if s == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return 0, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return strconv.ParseFloat(s, 64) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if inValue.Bool() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return 1, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return 0, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return float64(inValue.Int()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return float64(inValue.Uint()), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Float32, reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return inValue.Float(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return 0, fmt.Errorf("No known conversion from " + inValue.Type().String() + " to float") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func setField(field reflect.Value, value string, omitEmpty bool) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if field.Kind() == reflect.Ptr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if omitEmpty && value == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if field.IsNil() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			field.Set(reflect.New(field.Type().Elem())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		field = field.Elem() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch field.Interface().(type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case string: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		s, err := toString(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		field.SetString(s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		b, err := toBool(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		field.SetBool(b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case int, int8, int16, int32, int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		i, err := toInt(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		field.SetInt(i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case uint, uint8, uint16, uint32, uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		ui, err := toUint(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		field.SetUint(ui) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case float32, float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		f, err := toFloat(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		field.SetFloat(f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// Not a native type, check for unmarshal method 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if err := unmarshall(field, value); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if _, ok := err.(NoUnmarshalFuncError); !ok { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Could not unmarshal, check for kind, e.g. renamed type from basic type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			switch field.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				s, err := toString(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				field.SetString(s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				b, err := toBool(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				field.SetBool(b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				i, err := toInt(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				field.SetInt(i) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				ui, err := toUint(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				field.SetUint(ui) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case reflect.Float32, reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				f, err := toFloat(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				field.SetFloat(f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func getFieldAsString(field reflect.Value) (str string, err error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch field.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Interface: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case reflect.Ptr: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if field.IsNil() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return "", nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return getFieldAsString(field.Elem()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case int, int8, int16, int32, int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			str, err = toString(field.Int()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case uint, uint8, uint16, uint32, uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			str, err = toString(field.Uint()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case float32: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			str, err = toString(float32(field.Float())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		case float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			str, err = toString(field.Float()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			// Not a native type, check for marshal method 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			str, err = marshall(field) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				if _, ok := err.(NoMarshalFuncError); !ok { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				// If not marshal method, is field compatible with/renamed from native type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				switch field.Kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case reflect.String: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return field.String(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case reflect.Bool: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					str, err = toString(field.Bool()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					str, err = toString(field.Int()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					str, err = toString(field.Uint()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case reflect.Float32: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					str, err = toString(float32(field.Float())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case reflect.Float64: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					str, err = toString(field.Float()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					if err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						return str, err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return str, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return str, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// -------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Un/serializations helpers 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func unmarshall(field reflect.Value, value string) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dupField := field 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unMarshallIt := func(finalField reflect.Value) error { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if finalField.CanInterface() && finalField.Type().Implements(unMarshallerType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err := finalField.Interface().(TypeUnmarshaller).UnmarshalCSV(value); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else if finalField.CanInterface() && finalField.Type().Implements(textUnMarshalerType) { // Otherwise try to use TextMarshaller 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			if err := finalField.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(value)); err != nil { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return NoUnmarshalFuncError{"No known conversion from string to " + field.Type().String() + ", " + field.Type().String() + " does not implement TypeUnmarshaller"} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if dupField.IsNil() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			dupField = reflect.New(field.Type().Elem()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			field.Set(dupField) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return unMarshallIt(dupField) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dupField = dupField.Elem() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if dupField.CanAddr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return unMarshallIt(dupField.Addr()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return NoUnmarshalFuncError{"No known conversion from string to " + field.Type().String() + ", " + field.Type().String() + " does not implement TypeUnmarshaller"} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func marshall(field reflect.Value) (value string, err error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	dupField := field 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	marshallIt := func(finalField reflect.Value) (string, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if finalField.CanInterface() && finalField.Type().Implements(marshallerType) { // Use TypeMarshaller when possible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return finalField.Interface().(TypeMarshaller).MarshalCSV() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else if finalField.CanInterface() && finalField.Type().Implements(textMarshalerType) { // Otherwise try to use TextMarshaller 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			text, err := finalField.Interface().(encoding.TextMarshaler).MarshalText() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return string(text), err 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} else if finalField.CanInterface() && finalField.Type().Implements(stringerType) { // Otherwise try to use Stringer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return finalField.Interface().(Stringer).String(), nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return value, NoMarshalFuncError{"No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implement TypeMarshaller nor Stringer"} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	for dupField.Kind() == reflect.Interface || dupField.Kind() == reflect.Ptr { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		if dupField.IsNil() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			return value, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		dupField = dupField.Elem() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if dupField.CanAddr() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		return marshallIt(dupField.Addr()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return value, NoMarshalFuncError{"No known conversion from " + field.Type().String() + " to string, " + field.Type().String() + " does not implement TypeMarshaller nor Stringer"} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |