Documentation ¶
Overview ¶
Package conv provides a group of functions to convert between primitive types, maps, slices and structs.
Example ¶
// There is a group of shortcut functions for converting from/to simple types. // All conversion functions returns the converted value and an error. fmt.Println(conv.Int("123")) // -> 123 fmt.Println(conv.String(3.14)) // -> "3.14" fmt.Println(conv.Float64("invalid")) // -> get an error // When converting integers, overflow-checking is applied. fmt.Println(conv.Int8(1000)) // -> overflow // A zero value of number is converted to false; a non-zero value is converted to true. fmt.Println(conv.Bool(float32(0.0))) // -> false fmt.Println(conv.Bool(float64(0.1))) // -> true fmt.Println(conv.Bool(-1)) // -> true // strconv.ParseBool() is used for string-to-bool conversion. fmt.Println(conv.Bool("true")) // -> true fmt.Println(conv.Bool("false")) // -> false // Numbers can be converted time.Time, they're treated as UNIX timestamp. // NOTE: The location of the time depends on the input type, see the example of time for more details. t, err := conv.Time(3600) // An hour later after 1970-01-01T00:00:00Z. // By default time.Time is converted to string with the RFC3339 format. fmt.Println(conv.String(t.UTC())) // -> 1970-01-01T01:00:00Z // ConvertType() is the core function in the package. In fact all conversion can be done via // this function. For complex types, there is no shortcut, we can use ConvertType() directly. // It receives the source value and the destination type. // Convert from a slice to another. ConvertType() is applied to each element. sliceOfInt, err := conv.ConvertType([]string{"1", "2", "3"}, reflect.TypeOf([]int{})) fmt.Println(sliceOfInt, err) // -> []int{1, 2, 3} // Convert from a map[string]interface{} to a struct. ConvertType() is applied to each field. user := DemoUser{Name: "Bob", MailAddr: "bob@example.org", Age: 51} out, err := conv.ConvertType(user, reflect.TypeOf(map[string]interface{}{})) fmt.Println(out, err) // -> map[string]interface{}{"Age":51, "MailAddr":"bob@example.org", "Name":"Bob", "IsVip":false} // From map to struct. m := map[string]interface{}{"Name": "Alice", "Age": "27", "IsVip": 1} out, err = conv.ConvertType(m, reflect.TypeOf(user)) fmt.Printf("%+v\n", out) // -> DemoUser{Name: "Alice", MailAddr: "", Age: 27, IsVip:true} // Deep-clone a struct. out, err = conv.ConvertType(user, reflect.TypeOf(user)) fmt.Printf("%+v\n", out) // -> DemoUser{Name: "Bob", MailAddr: "bob@example.org", Age: 51} // Convert() is similar to ConvertType(), but receive a pointer instead of a type. // It's more like some functions in the standard library such as json.Unmarshal(). clone := DemoUser{} conv.Convert(user, &clone) fmt.Printf("%+v\n", clone) // -> DemoUser{Name: "Bob", MailAddr: "bob@example.org", Age: 51}
Output: 123 <nil> 3.14 <nil> 0 strconv.ParseFloat: parsing "invalid": invalid syntax 0 value overflow when converting 1000 (int) to int8 false <nil> true <nil> true <nil> true <nil> false <nil> 1970-01-01T01:00:00Z <nil> [1 2 3] <nil> map[Age:51 IsVip:false MailAddr:bob@example.org Name:Bob] <nil> {Name:Alice MailAddr: Age:27 IsVip:true} {Name:Bob MailAddr:bob@example.org Age:51 IsVip:false} {Name:Bob MailAddr:bob@example.org Age:51 IsVip:false}
Example (CustomConverters) ¶
// We can use conv.ConvertFunc to convert values to some type of your own. type Name struct{ FirstName, LastName string } // Converts a string such as "A B" to a struct Name{A, B}. nameConverter := func(value interface{}, typ reflect.Type) (result interface{}, err error) { if typ != reflect.TypeOf(Name{}) { return nil, nil } s, ok := value.(string) if !ok { return nil, nil } parts := strings.Split(s, " ") if len(parts) != 2 { return nil, errors.New("bad name") } return Name{parts[0], parts[1]}, nil } c := &conv.Conv{ Conf: conv.Config{ CustomConverters: []conv.ConvertFunc{nameConverter}, }, } var name Name c.Convert("John Doe", &name) fmt.Println("FirstName:", name.FirstName) fmt.Println("LastName:", name.LastName) // The middle name is not supported so we'll get an error here. fmt.Println("error:") _, err := c.ConvertType("John Middle Doe", reflect.TypeOf(Name{})) fmt.Println(err)
Output: FirstName: John LastName: Doe error: conv.ConvertType: converter[0]: bad name
Example (TheConvInstance) ¶
// The Conv struct providers the underlying features for all shortcuts functions. // You can use it directly. A zero value has the default behavior. c := new(conv.Conv) // It has a field named Conf which is used to customize the conversion. // By default, we get an error when converting to a slice from a string that is a group of // elements separated by some characters. fmt.Println(c.ConvertType("1,2,3", reflect.TypeOf([]int{}))) // -> error // Conf.StringSplitter is a function that defines how to convert from a string to a slice. c.Conf.StringSplitter = func(v string) []string { return strings.Split(v, ",") } // After configure, the conversion should be OK. fmt.Println(c.ConvertType("1,2,3", reflect.TypeOf([]int{}))) // -> []int{1, 2, 3} // Conf.FieldMatcherCreator define how to match names from a struct when converting from // a map or another struct. // Here we demonstrate how to make snake-case names match the field names automatically, // using the build-in FieldMatcherCreator named SimpleMatcherCreator. c.Conf.FieldMatcherCreator = &conv.SimpleMatcherCreator{ Conf: conv.SimpleMatcherConfig{ CamelSnakeCase: true, }, } // When then CamelSnakeCase option is true, 'mailAddr' can match the field MailAddr, 'is_vip' can match IsVip. m := map[string]interface{}{"name": "Bob", "age": "51", "mailAddr": "bob@example.org", "is_vip": "true"} user := DemoUser{} _ = c.Convert(m, &user) fmt.Printf("%+v\n", user) // -> DemoUser{Name: "Bob", MailAddr: "bob@example.org", Age: 51, IsVip: true}) // The json package of the standard library does not support matching fields in case-insensitive manner. // We have to use field tag to specify the name of JSON properties. // With FieldMatcherCreator, we can unmarshal JSON in case-insensitive manner, using a map as a middleware. // Thou the performance is not good, but it works :) . middleware := make(map[string]interface{}) _ = json.Unmarshal([]byte(`{"name":"Alice", "mailAddr":"alice@example.org", "isVip": true, "age":27}`), &middleware) _ = c.Convert(middleware, &user) fmt.Printf("%+v\n", user) // -> DemoUser{Name: "Alice", MailAddr: "alice@example.org", Age: 27, IsVip: true})
Output: <nil> conv.ConvertType: conv.StringToSlice: cannot convert to []int, at index 0: conv.SimpleToSimple: strconv.ParseInt: parsing "1,2,3": invalid syntax [1 2 3] <nil> {Name:Bob MailAddr:bob@example.org Age:51 IsVip:true} {Name:Alice MailAddr:alice@example.org Age:27 IsVip:true}
Example (TimeConversion) ¶
// When converting to a time.Time, the location depends on the input value. // When converting a number to a Time, returns a Time with the location time.Local, behaves like time.Unix(). t, _ := conv.Time(0) // Shortcut of conv.ConvertType(0, reflect.TypeOf(time.Time{})) . fmt.Println("convert a number to a Time, the output location is:", t.Location()) // -> Local // Returns a Time with offset 02:00, like time.Parse(). t, _ = conv.Time("2022-04-20T11:30:40+02:00") _, offset := t.Zone() fmt.Println(offset) // -> 7200 which is the total seconds of 02:00. // Returns a Time with time.UTC, like time.Parse(). t, _ = conv.Time("2022-04-20T11:30:40Z") fmt.Println(t.Location()) // -> UTC // When converting a Time to a Time, keeps the location: the raw value is cloned. t, _ = conv.Time(time.Now()) fmt.Println("convert a Local time to a Local time, the output location is:", t.Location()) // -> Local t, _ = conv.Time(time.Now().UTC()) fmt.Println("convert an UTC time to an UTC time, the output location is:", t.Location()) // -> UTC // When converting a Time to a number, outputs an UNIX timestamp. t, _ = time.Parse(time.RFC3339, "2022-04-20T03:30:40Z") fmt.Println(conv.MustInt(t)) // -> 1650425440 // When converting a Time to a string, outputs using conv.DefaultTimeToString function, which format the time in RFC3339. fmt.Println(conv.MustString(t)) // -> 2022-04-20T03:30:40Z
Output: convert a number to a Time, the output location is: Local 7200 UTC convert a Local time to a Local time, the output location is: Local convert an UTC time to an UTC time, the output location is: UTC 1650425440 2022-04-20T03:30:40Z
Index ¶
- func Bool(v interface{}) (bool, error)
- func Complex128(v interface{}) (complex128, error)
- func Complex64(v interface{}) (complex64, error)
- func Convert(src interface{}, dstPtr interface{}) error
- func ConvertType(src interface{}, dstTyp reflect.Type) (interface{}, error)
- func DefaultStringToTime(v string) (time.Time, error)
- func DefaultTimeToString(t time.Time) (string, error)
- func Float32(v interface{}) (float32, error)
- func Float64(v interface{}) (float64, error)
- func Int(v interface{}) (int, error)
- func Int16(v interface{}) (int16, error)
- func Int32(v interface{}) (int32, error)
- func Int64(v interface{}) (int64, error)
- func Int8(v interface{}) (int8, error)
- func IsPrimitiveKind(k reflect.Kind) bool
- func IsPrimitiveType(t reflect.Type) bool
- func IsSimpleType(t reflect.Type) bool
- func MapToStruct(m map[string]interface{}, dstTyp reflect.Type) (interface{}, error)
- func MustBool(v interface{}) bool
- func MustConvert(src interface{}, dstPtr interface{})
- func MustConvertType(src interface{}, dstTyp reflect.Type) interface{}
- func MustFloat32(v interface{}) float32
- func MustFloat64(v interface{}) float64
- func MustInt(v interface{}) int
- func MustInt16(v interface{}) int16
- func MustInt32(v interface{}) int32
- func MustInt64(v interface{}) int64
- func MustInt8(v interface{}) int8
- func MustMapToStruct(m map[string]interface{}, dstTyp reflect.Type) interface{}
- func MustString(v interface{}) string
- func MustStructToMap(v interface{}) map[string]interface{}
- func MustUint(v interface{}) uint
- func MustUint16(v interface{}) uint16
- func MustUint32(v interface{}) uint32
- func MustUint64(v interface{}) uint64
- func MustUint8(v interface{}) uint8
- func String(v interface{}) (string, error)
- func StructToMap(v interface{}) (map[string]interface{}, error)
- func Time(v interface{}) (time.Time, error)
- func Uint(v interface{}) (uint, error)
- func Uint16(v interface{}) (uint16, error)
- func Uint32(v interface{}) (uint32, error)
- func Uint64(v interface{}) (uint64, error)
- func Uint8(v interface{}) (uint8, error)
- type Config
- type Conv
- func (c *Conv) Convert(src interface{}, dstPtr interface{}) error
- func (c *Conv) ConvertType(src interface{}, dstTyp reflect.Type) (interface{}, error)
- func (c *Conv) MapToMap(m interface{}, typ reflect.Type) (interface{}, error)
- func (c *Conv) MapToStruct(m map[string]interface{}, dstTyp reflect.Type) (interface{}, error)
- func (c *Conv) MustConvert(src interface{}, dstPtr interface{})
- func (c *Conv) MustConvertType(src interface{}, dstTyp reflect.Type) interface{}
- func (c *Conv) SimpleToBool(simple interface{}) (bool, error)
- func (c *Conv) SimpleToSimple(src interface{}, dstTyp reflect.Type) (interface{}, error)
- func (c *Conv) SimpleToString(v interface{}) (string, error)
- func (c *Conv) SliceToSlice(src interface{}, dstSliceTyp reflect.Type) (interface{}, error)
- func (c *Conv) StringToSlice(v string, simpleSliceType reflect.Type) (interface{}, error)
- func (c *Conv) StructToMap(v interface{}) (map[string]interface{}, error)
- func (c *Conv) StructToStruct(src interface{}, dstTyp reflect.Type) (interface{}, error)
- type ConvertFunc
- type FieldInfo
- type FieldMatcher
- type FieldMatcherCreator
- type FieldWalker
- type SimpleMatcherConfig
- type SimpleMatcherCreator
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bool ¶
Bool converts the given value to the corresponding value of bool. The value must be simple, for which IsSimpleType() returns true. It is equivalent to new(Conv).SimpleToBool(v) .
func Complex128 ¶
func Complex128(v interface{}) (complex128, error)
Complex128 converts the given value to the corresponding value of complex128. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(complex128(0+0i))) .
func Complex64 ¶
Complex64 converts the given value to the corresponding value of complex64. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(complex64(0+0i))) .
func Convert ¶
func Convert(src interface{}, dstPtr interface{}) error
Convert is equivalent to new(Conv).Convert() .
func ConvertType ¶
ConvertType is equivalent to new(Conv).ConvertType() .
func DefaultStringToTime ¶
DefaultStringToTime parses the time using the time.RFC3339Nano format.
func DefaultTimeToString ¶
DefaultTimeToString formats time using the time.RFC3339 format.
func Float32 ¶
Float32 converts the given value to the corresponding value of float32. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(float32(0))) .
func Float64 ¶
Float64 converts the given value to the corresponding value of float64. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(float64(0))) .
func Int ¶
Int converts the given value to the corresponding value of int. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(int(0))) .
func Int16 ¶
Int16 converts the given value to the corresponding value of int16. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(int16(0))) .
func Int32 ¶
Int32 converts the given value to the corresponding value of int32. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(int32(0))) .
func Int64 ¶
Int64 converts the given value to the corresponding value of int64. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(int64(0))) .
func Int8 ¶
Int8 converts the given value to the corresponding value of int8. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(int8(0))) .
func IsPrimitiveKind ¶
IsPrimitiveKind returns true if the given Kind is any of bool, int*, uint*, float*, complex* or string.
func IsPrimitiveType ¶
IsPrimitiveType returns true if the given type is any of bool, int*, uint*, float*, complex* or string.
func IsSimpleType ¶
IsSimpleType returns true if the given type IsPrimitiveType() or is convertible to time.Time .
func MapToStruct ¶
MapToStruct is equivalent to new(Conv).MapToStruct() .
func MustBool ¶ added in v0.2.0
func MustBool(v interface{}) bool
MustBool is like Bool() but panics instead of returns an error.
func MustConvert ¶ added in v0.2.0
func MustConvert(src interface{}, dstPtr interface{})
MustConvert is equivalent to new(Conv).MustConvert() .
func MustConvertType ¶ added in v0.2.0
MustConvertType is equivalent to new(Conv).MustConvertType() .
func MustFloat32 ¶ added in v0.2.0
func MustFloat32(v interface{}) float32
MustFloat32 is like Float32() but panics instead of returns an error.
func MustFloat64 ¶ added in v0.2.0
func MustFloat64(v interface{}) float64
MustFloat64 is like Float64() but panics instead of returns an error.
func MustInt ¶ added in v0.2.0
func MustInt(v interface{}) int
MustInt is like Int() but panics instead of returns an error.
func MustInt16 ¶ added in v0.2.0
func MustInt16(v interface{}) int16
MustInt16 is like Int16() but panics instead of returns an error.
func MustInt32 ¶ added in v0.2.0
func MustInt32(v interface{}) int32
MustInt32 is like Int32() but panics instead of returns an error.
func MustInt64 ¶ added in v0.2.0
func MustInt64(v interface{}) int64
MustInt64 is like Int64() but panics instead of returns an error.
func MustInt8 ¶ added in v0.2.0
func MustInt8(v interface{}) int8
MustInt8 is like Int8() but panics instead of returns an error.
func MustMapToStruct ¶ added in v0.2.0
MustMapToStruct is like MapToStruct() but panics instead of returns an error.
func MustString ¶ added in v0.2.0
func MustString(v interface{}) string
MustString is like String() but panics instead of returns an error.
func MustStructToMap ¶ added in v0.2.0
func MustStructToMap(v interface{}) map[string]interface{}
MustStructToMap is like StructToMap() but panics instead of returns an error.
func MustUint ¶ added in v0.2.0
func MustUint(v interface{}) uint
MustUint is like Uint() but panics instead of returns an error.
func MustUint16 ¶ added in v0.2.0
func MustUint16(v interface{}) uint16
MustUint16 is like Uint16() but panics instead of returns an error.
func MustUint32 ¶ added in v0.2.0
func MustUint32(v interface{}) uint32
MustUint32 is like Uint32() but panics instead of returns an error.
func MustUint64 ¶ added in v0.2.0
func MustUint64(v interface{}) uint64
MustUint64 is like Uint64() but panics instead of returns an error.
func MustUint8 ¶ added in v0.2.0
func MustUint8(v interface{}) uint8
MustUint8 is like Uint8() but panics instead of returns an error.
func String ¶
String converts the given value to the corresponding value of string. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).SimpleToString(v) .
func StructToMap ¶
StructToMap is equivalent to new(Conv).StructToMap() .
func Time ¶
Time converts the given value to the corresponding value of time.Time. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).SimpleToSimple(v, reflect.TypeOf(time.Time{})) .
func Uint ¶
Uint converts the given value to the corresponding value of uint. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(uint(0))) .
func Uint16 ¶
Uint16 converts the given value to the corresponding value of uint16. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(uint(0))) .
func Uint32 ¶
Uint32 converts the given value to the corresponding value of uint32. The value must be a simple type, for which IsSimpleType() returns true. It is equivalent to new(Conv).Convert(v, reflect.TypeOf(uint(0))) .
Types ¶
type Config ¶
type Config struct { // StringSplitter is the function used to split the string into elements of the slice when converting a string to a slice. // It is called internally by Convert(), ConvertType() or other functions. // Set this field if customization of the conversion is needed. // If this field is nil, the value will not be split. StringSplitter func(v string) []string // FieldMatcherCreator is used to get FieldMatcher instances when converting from map to struct or // from struct to struct. // // When converting a map to a struct, a FieldMatcherCreator.GetMatcher() returns a FieldMatcher instance for the // target struct, then FieldMatcher.MatchField() is applied to each key of the map. // The matched field will be set by the converted value of the key, the value is converted with Conv.ConvertType(). // // When converting a struct to another, FieldMatcher.MatchField() is applied to each field name from the source struct. // // If FieldMatcherCreator is nil, SimpleMatcherCreator() will be used. There are some predefined implementations, // such as CaseInsensitiveFieldMatcherCreator(), CamelSnakeCaseFieldMatcherCreator(). FieldMatcherCreator FieldMatcherCreator // CustomConverters provides a group of functions for converting the given value to some specific type. // The target type will never be nil. // // These functions are used to customize the conversion. // It is only used by Convert() or ConvertType(), not works in other functions. // // When a conversion starts, it will firstly go through each function in this slice: // - The conversion stops immediately when some function returns a non-nil result or an error. // Convert() or ConvertType() will use the result or returns the error directly. // - The conversion runs next function in the slice if the previous one return nil with no error. // - If no function in the slice returns OK, the conversion will continue with the predefined implementations, // such as MapToMap(), StructToMap(), etc. // // NOTE: If your ConvertFunc use Conv internally, be carefully if there will be infinity loops. Is it suggested to // use a Conv instance with no ConvertFunc for the internal conversions. CustomConverters []ConvertFunc // TimeToString formats the given time. // It is called internally by Convert(), ConvertType() or other functions. // Set this field if it is needed to customize the procedure. // If this field is nil, the function DefaultTimeToString() will be used. TimeToString func(t time.Time) (string, error) // StringToTime parses the given string and returns the time it represents. // It is called internally by Convert, ConvertType or other functions. // Set this field if it is needed to customize the procedure. // If this field is nil, the function DefaultStringToTime() will be used. StringToTime func(v string) (time.Time, error) }
Config is used to customize the conversion behavior of Conv .
type Conv ¶
type Conv struct { // Conf is used to customize the conversion behavior. Conf Config }
Conv provides a group of functions to convert between simple types, maps, slices and structs. A pointer of a zero value is ready to use, it has the default behavior:
new(Conv).ConvertType(...)
The field Config is used to customize the conversion behavior. e.g., this Conv instance uses a built-in FieldMatcherCreator and a custom TimeToString function.
c:= &Conv{ Config: Config { FieldMatcherCreator: CaseInsensitiveFieldMatcherCreator(), TimeToString: func(t time.Time) (string, error) { return t.Format(time.RFC1123), nil }, }, }
All functions are thread-safe and can be used concurrently.
func (*Conv) Convert ¶
Convert is like Conv.ConvertType() , but receives a pointer instead of a type. It stores the result in the value pointed to by dst.
If the source value is nil, the function returns without an error, the underlying value of the pointer will not be set. If dst is not a pointer, the function panics an error.
func (*Conv) ConvertType ¶
ConvertType is the core function of Conv . It converts the given value to the destination type.
Currently, these conversions are supported:
simple -> simple use Conv.SimpleToSimple() string -> []simple use Conv.StringToSlice() map[string]interface{} -> struct use Conv.MapToStruct() map[ANY]ANY -> map[ANY]ANY use Conv.MapToMap() []ANY -> []ANY use Conv.SliceToSlice() struct -> map[string]interface{} use Conv.StructToMap() struct -> struct use Conv.StructToStruct()
'ANY' generally can be any other type listed above. 'simple' is some type which IsSimpleType() returns true.
If the destination type is the type of the empty interface, the function returns src directly without any error.
For pointers: If the source value is a pointer, the value pointed to will be extracted and converted. The destination type can be a type of pointer, the source value which is nil will be converted to a nil pointer.
This function can be used to deep-clone a struct, e.g.:
clone, err := ConvertType(src, reflect.TypeOf(src))
There is a special conversion that can convert a map[string]interface{} to some other type listed above, when the map has only one key and the key is an empty string, the conversion is performed over the value other than the map itself. This is a special contract for some particular situation, when some code is working on maps only.
func (*Conv) MapToMap ¶
MapToMap converts a map to another map. If the source value is nil, the function returns a nil map of the destination type without any error.
All keys and values in the map are converted using Conv.ConvertType() .
func (*Conv) MapToStruct ¶
MapToStruct converts a map[string]interface{} to a struct.
Each exported field of the struct is indexed using Conv.Config.FieldMatcherCreator().
func (*Conv) MustConvert ¶ added in v0.2.0
func (c *Conv) MustConvert(src interface{}, dstPtr interface{})
MustConvert is like Convert() but panics instead of returns an error.
func (*Conv) MustConvertType ¶ added in v0.2.0
MustConvertType is like ConvertType() but panics instead of returns an error.
func (*Conv) SimpleToBool ¶
SimpleToBool converts the value to bool. The value must be simple, for which IsSimpleType() returns true.
Rules:
- nil: as false.
- Numbers: zero as false, non-zero as true.
- String: same as strconv.ParseBool().
- time.Time: zero Unix timestamps as false, other values as true.
- Other values are not supported, returns false and an error.
func (*Conv) SimpleToSimple ¶
SimpleToSimple converts a simple type, for which IsSimpleType() returns true, to another simple type. The conversion use the following rules:
Booleans:
- true/false is converted to number 0/1, or string '0'/'1'.
- From a boolean to a string: use strconv.ParseBool().
- From a number to a boolean: zero value as false; non-zero value as true.
Numbers:
- From a complex number to a real number: the imaginary part must be zero, the real part will be converted.
To time.Time:
- From a number: the number is treated as a Unix-timestamp as converted using time.Unix(), the time zone is time.Local.
- From a string: use Conv.Conf.StringToTime function.
- From another time.Time: the raw value is cloned, includes the timestamp and the location.
From time.Time:
- To a number: output a Unix-timestamp.
- To a string: use Conv.Conf.TimeToString function.
func (*Conv) SimpleToString ¶
SimpleToString converts the given value to a string. The value must be a simple type, for which IsSimpleType() returns true.
Conv.Config.StringToTime() is used to format times. Specially, booleans are converted to 0/1, not the default format true/false.
func (*Conv) SliceToSlice ¶
SliceToSlice converts a slice to another slice.
Each element will be converted using Conv.ConvertType() . A nil slice will be converted to a nil slice of the destination type. If the source value is nil interface{}, returns nil and an error.
func (*Conv) StringToSlice ¶
StringToSlice converts a string to a slice. The elements of the slice must be simple type, for which IsSimpleType() returns true.
Conv.Config.StringSplitter() is used to split the string.
func (*Conv) StructToMap ¶
StructToMap is partially like json.Unmarshal(json.Marshal(v), &someMap) . It converts a struct to map[string]interface{} .
Each value of exported field will be processed recursively with an internal function f() , which:
Simple types, for which IsSimpleType() returns true:
- A type whose kind is primitive, will be converted to a primitive value.
- For other types, the value will be cloned into the map directly.
Slices:
- A nil slice is converted to a nil slice; an empty slice is converted to an empty slice with cap=0.
- A non-empty slice is converted to another slice, each element is process with f() , all elements must be the same type.
Maps:
- A nil map are converted to nil of map[string]interface{} .
- A non-nil map is converted to map[string]interface{} , keys are processed with Conv.ConvertType() , values with f() .
Structs are converted to map[string]interface{} using Conv.StructToMap() recursively.
Pointers:
- Nils are ignored.
- Non-nil values pointed to are converted with f() .
Other types not listed above are not supported and will result in an error.
func (*Conv) StructToStruct ¶
StructToStruct converts a struct to another. If the given value is nil, returns nil and an error.
When converting, each field of the destination struct is indexed using Conv.Config.FieldMatcherCreator. The field values are converted using Conv.ConvertType() .
This function can be used to deep-clone a struct.
type ConvertFunc ¶ added in v0.6.0
ConvertFunc is used to customize the conversion.
type FieldInfo ¶ added in v0.4.1
type FieldInfo struct { reflect.StructField // If the field is a field of am embedded and untagged field which type is struct, // the path is a dot-split string like A.B.C; otherwise it's equal to F.Name. Path string // The tag value of the field. TagValue string }
FieldInfo describes a field in a struct.
type FieldMatcher ¶
type FieldMatcher interface { // MatchField returns the first matched field for the given name; // if no name can match, returns a zero value and false. // The field returned must be an exported field. MatchField(name string) (field reflect.StructField, ok bool) }
FieldMatcher is used to match names when converting from map to struct or from struct to struct.
type FieldMatcherCreator ¶
type FieldMatcherCreator interface { // GetMatcher returns a FieldMatcher for the given type of struct. // If the type is not Struct, it panics. GetMatcher(typ reflect.Type) FieldMatcher }
FieldMatcherCreator is used to create FieldMatcher instances when converting from map to struct or from struct to struct.
type FieldWalker ¶ added in v0.4.1
type FieldWalker struct {
// contains filtered or unexported fields
}
FieldWalker is used to traverse all field of a struct.
The traverse will go into each level of embedded and untagged structs. Unexported fields are ignored. It reads fields in this order:
- Tagged fields.
- Non-embedded struct or non-struct fields.
- Fields of embedded struct, recursively.
e.g. without tagName
type Ec struct { D int } type Eb struct { B int // hided by T.B Ec // hided by T.Ec.D C int } type T struct { A int Eb B string // hides Eb.B Ec }
The traverse order is:
PATH INDEX A {0} B {2} Eb.C {1, 2} Ec.D {3, 0}
e.g. with tagName="json"
type A struct { A int X int // hided by T.B } type B struct { B1 int // absent B2 int // absent } type T struct { A B `json:"X"` // hides B.X, the traverse will not go into the field }
The traverse order is:
PATH INDEX TAG B {1} X A.A {0, 0}
func NewFieldWalker ¶ added in v0.4.1
func NewFieldWalker(typ reflect.Type, tagName string) *FieldWalker
NewFieldWalker creates a new instance of FieldWalker. When tagName is specified, the values of the tag will be filled into FieldInfo.TagValue during the traversal.
func (*FieldWalker) WalkFields ¶ added in v0.4.1
func (walker *FieldWalker) WalkFields(callback func(FieldInfo) bool)
WalkFields walks through fields of the given type of struct (or pointer) with a breadth-first traverse. Each field will be send to the callback function. If the function returns false, the traverse stops.
func (*FieldWalker) WalkValues ¶ added in v0.4.1
func (walker *FieldWalker) WalkValues(value reflect.Value, callback func(FieldInfo, reflect.Value) bool)
WalkValues is like WalkFields(), but walks through all field values.
If a struct is embedded as a pointer, and the value is nil, the field is ignored. If the given value is nil, the traverse stops with no callback.
type SimpleMatcherConfig ¶
type SimpleMatcherConfig struct { // Tag specifies the tag name for the fields. When a name is given by the tag, the matcher // matches the field using the given name; otherwise the raw field name is used. // The tag works like some commonly used tags such as 'json', 'xml'. // Tag can be empty. // // e.g. When 'conv' is given as the tag name, the matcher returns the OldName field when // indexing 'NewName'. // type Target struct { // OldName int `conv:"NewName"` // 'NewName' can match this field. // RawName // No tag specified, use 'RawName' for field matching. // } // Tag string // CaseInsensitive specifies whether the matcher matches field names in a case-insensitive manner. // If this field is true, CamelSnakeCase is ignored. // // If the field is true, 'ab', 'Ab', 'aB', 'AB' are equal. // CaseInsensitive bool // OmitUnderscore specifies whether to omit underscores in field names. // If this field is true, CamelSnakeCase is ignored. // // If the field is true, 'ab', 'a_b', '_ab', 'a__b_' are equal. // OmitUnderscore bool // CamelSnakeCase whether to support camel-case and snake-case name comparing. // If CaseInsensitive or OmitUnderscore is true, this field is ignored. // // When it is set to true, the matcher can match names in camel-case or snake-case form, such as // 'lowerCaseCamel' or 'UpperCaseCamel' or 'snake_case' or 'Snake_Case' (sometimes called train-case). // // The first rune of each word is compared case-insensitively; others are compared in the case-sensitive // manner. For example: // - These names are equal: aaBB, AaBb, aa_bb, Aa_Bb, aa_BB // - These names are not equal: aa_bb, Aabb, aabB, _aaBb, AaBb_, Aa__Bb // // Mostly this option can be used to match field names that come from different platform, e.g., // 'lowerCaseCamel' from Javascript, 'UpperCaseCamel' from Go, 'snake_case' from Mysql database. // CamelSnakeCase bool }
SimpleMatcherConfig configures SimpleMatcherCreator.
type SimpleMatcherCreator ¶
type SimpleMatcherCreator struct { Conf SimpleMatcherConfig // contains filtered or unexported fields }
SimpleMatcherCreator returns an instance of FieldMatcherCreator. It is used as the default value when Conv.Config.FieldMatcher is nil.
func (*SimpleMatcherCreator) GetMatcher ¶
func (c *SimpleMatcherCreator) GetMatcher(typ reflect.Type) FieldMatcher
GetMatcher implements FieldMatcherCreator.GetMatcher().