Documentation ¶
Overview ¶
Package conv provides fast and intuitive conversions across Go types.
Example ¶
package main import ( "fmt" conv "github.com/cstockton/go-conv" ) func main() { // Basic types fmt.Printf("Basics:\n `TRUE` -> %#v\n `1.23` -> %#v\n `1m2s` -> %#v\n\n", conv.Bool("YES"), conv.Int64("12.3"), conv.Duration("1m2s")) // Slice and map support from := []string{"1.2", "34.5", "-678.9"} var into []float64 conv.Slice(&into, from) // type inferred from the element of `into` fmt.Printf("Slice:\n %#v\n -> %#v\n\n", from, into) }
Output: Basics: `TRUE` -> true `1.23` -> 12 `1m2s` -> 62000000000 Slice: []string{"1.2", "34.5", "-678.9"} -> []float64{1.2, 34.5, -678.9}
Example (Bools) ¶
Bool Conversions supports all the paths provided by the standard libraries strconv.ParseBool when converting from a string, all other conversions are simply true when not the types zero value. As a special case zero length map and slice types are also false, even if initialized.
package main import ( "fmt" "time" conv "github.com/cstockton/go-conv" ) func main() { // Bool conversion from other bool values will be returned without // modification. fmt.Println(conv.Bool(true), conv.Bool(false)) // Bool conversion from strings consider the following values true: // "t", "T", "true", "True", "TRUE", // "y", "Y", "yes", "Yes", "YES", "1" // // It considers the following values false: // "f", "F", "false", "False", "FALSE", // "n", "N", "no", "No", "NO", "0" fmt.Println(conv.Bool("T"), conv.Bool("False")) // Bool conversion from other supported types will return true unless it is // the zero value for the given type. fmt.Println(conv.Bool(int64(123)), conv.Bool(int64(0))) fmt.Println(conv.Bool(time.Duration(123)), conv.Bool(time.Duration(0))) fmt.Println(conv.Bool(time.Now()), conv.Bool(time.Time{})) // All other types will return false. fmt.Println(conv.Bool(struct{ string }{""})) }
Output: true false true false true false true false true false false
Example (Durations) ¶
Duration conversion supports all the paths provided by the standard libraries time.ParseDuration when converting from strings, with a couple enhancements outlined below.
package main import ( "fmt" "time" conv "github.com/cstockton/go-conv" ) func main() { // Duration conversion from other time.Duration values will be returned // without modification. fmt.Println(conv.Duration(time.Duration(time.Second))) // 1s fmt.Println(conv.Duration("1h30m")) // 1h30m0s // Duration conversions from floats will separate the integer // and fractional portions into a more natural conversion. fmt.Println(conv.Duration("12.15")) // All other duration conversions from numeric types assign the // elapsed nanoseconds using Go conversions. fmt.Println(conv.Duration(`123456`)) // 34h17m36s }
Output: 1s 1h30m0s 12.15s 34h17m36s
Example (Maps) ¶
Map conversion will infer the conversion functions to use from the key and element types of the given map. The second argument will be walked as described in the supporting package, go-iter.
An error is returned if the below restrictions are not met:
- It must be a non-pointer, non-nil initialized map
- Both the key and element T must be supported by this library
- The key must be a value T, the element may be a T or *T
Excerpt from github.com/cstockton/go-iter iter.Walk:
Walk will recursively walk the given interface value as long as an error does not occur. The pair func will be given a interface value for each value visited during walking and is expected to return an error if it thinks the traversal should end. A nil value and error is given to the walk func if an inaccessible value (can't reflect.Interface()) is found.
Walk is called on each element of maps, slices and arrays. If the underlying iterator is configured for channels it receives until one fails. Channels should probably be avoided as ranging over them is more concise.
package main import ( "fmt" "log" "sort" conv "github.com/cstockton/go-conv" ) func main() { // Map must be initialized into := make(map[string]int64) // No need to pass a pointer err := conv.Map(into, []string{"123", "456", "6789"}) if err != nil { log.Fatal("err:", err) } // This is just for testing determinism since keys are randomized. var keys []string for k := range into { keys = append(keys, k) } sort.Strings(keys) // Print the keys for _, k := range keys { fmt.Println("k:", k, "v:", into[k]) } }
Output: k: 0 v: 123 k: 1 v: 456 k: 2 v: 6789
Example (Numerics) ¶
Numeric conversion from other numeric values of an identical type will be returned without modification. Numeric conversions deviate slightly from Go when dealing with under/over flow. When performing a conversion operation that would overflow, we instead assign the maximum value for the target type. Similarly, conversions that would underflow are assigned the minimun value for that type, meaning unsigned integers are given zero values isntead of spilling into large positive integers.
package main import ( "fmt" conv "github.com/cstockton/go-conv" ) func main() { // For more natural Float -> Integer when the underlying value is a string. // Conversion functions will always try to parse the value as the target type // first. If parsing fails float parsing with truncation will be attempted. fmt.Println(conv.Int(`-123.456`)) // -123 // This does not apply for unsigned integers if the value is negative. Instead // performing a more intuitive (to the human) truncation to zero. fmt.Println(conv.Uint(`-123.456`)) // 0 }
Output: -123 0
Example (Overview) ¶
All methods and functions accept any type of value for conversion, if unable to find a reasonable conversion path they will return the target types zero value. The Conv struct will also report an error on failure, while all the top level functions (conv.Bool(...), conv.Time(...), etc) will only return a single value for cases that you wish to leverage zero values. These functions are powered by the "DefaultConverter" variable so you may replace it with your own Converter or a Conv struct to adjust behavior.
package main import ( "fmt" conv "github.com/cstockton/go-conv" ) func main() { // All top level conversion functions discard errors, returning the types zero // value instead. fmt.Println(conv.Time("bad time string")) // time.Time{} fmt.Println(conv.Time("Sat Mar 7 11:06:39 PST 2015")) // Conversions are allowed as long as the underlying type is convertable, for // example: type MyString string fmt.Println(conv.Int(MyString(`123`))) // 123 // Pointers will be dereferenced when appropriate. s := `123` fmt.Println(conv.Int(&s)) // 123 // If you would like to know if errors occur you may use a conv.Conv. It is // safe for use by multiple Go routines and needs no initialization. var c conv.Conv i, err := c.Int(`Foo`) // Got 0 because of err: cannot convert "Foo" (type string) to int fmt.Printf("Got %v because of err: %v", i, err) }
Output: 0001-01-01 00:00:00 +0000 UTC 2015-03-07 11:06:39 +0000 PST 123 123 Got 0 because of err: cannot convert "Foo" (type string) to int
Example (Panics) ¶
In short, panics should not occur within this library under any circumstance. This obviously excludes any oddities that may surface when the runtime is not in a healthy state, i.e. uderlying system instability, memory exhaustion. If you are able to create a reproducible panic please file a bug report.
package main import ( "fmt" conv "github.com/cstockton/go-conv" ) func main() { // The zero value for the target type is always returned. fmt.Println(conv.Bool(nil)) fmt.Println(conv.Bool([][]int{})) fmt.Println(conv.Bool((chan string)(nil))) fmt.Println(conv.Bool((*interface{})(nil))) fmt.Println(conv.Bool((*interface{})(nil))) fmt.Println(conv.Bool((**interface{})(nil))) }
Output: false false false false false false
Example (Slices) ¶
Slice conversion will infer the element type from the given slice, using the associated conversion function as the given structure is traversed recursively. The behavior if the value is mutated during iteration is undefined, though at worst an error will be returned as this library will never panic.
An error is returned if the below restrictions are not met:
- It must be a pointer to a slice, it does not have to be initialized
- The element must be a T or *T of a type supported by this library
package main import ( "fmt" "log" conv "github.com/cstockton/go-conv" ) func main() { // Slice does not need initialized. var into []int64 // You must pass a pointer to a slice. err := conv.Slice(&into, []string{"123", "456", "6789"}) if err != nil { log.Fatal("err:", err) } for _, v := range into { fmt.Println("v:", v) } }
Output: v: 123 v: 456 v: 6789
Example (Strings) ¶
String conversion from any values outside the cases below will simply be the result of calling fmt.Sprintf("%v", value), meaning it can not fail. An error is still provided and you should check it to be future proof.
package main import ( "fmt" conv "github.com/cstockton/go-conv" ) func main() { // String conversion from other string values will be returned without // modification. fmt.Println(conv.String(`Foo`)) // As a special case []byte will also be returned after a Go string conversion // is applied. fmt.Println(conv.String([]byte(`Foo`))) // String conversion from types that do not have a valid conversion path will // still have sane string conversion for troubleshooting. fmt.Println(conv.String(struct{ msg string }{"Foo"})) }
Output: Foo Foo {Foo}
Index ¶
- func Bool(from interface{}) bool
- func Duration(from interface{}) time.Duration
- func Float32(from interface{}) float32
- func Float64(from interface{}) float64
- func Int(from interface{}) int
- func Int16(from interface{}) int16
- func Int32(from interface{}) int32
- func Int64(from interface{}) int64
- func Int8(from interface{}) int8
- func Map(into, from interface{}) error
- func Slice(into, from interface{}) error
- func String(from interface{}) string
- func Time(from interface{}) time.Time
- func Uint(from interface{}) uint
- func Uint16(from interface{}) uint16
- func Uint32(from interface{}) uint32
- func Uint64(from interface{}) uint64
- func Uint8(from interface{}) uint8
- type Conv
- func (c Conv) Bool(from interface{}) (bool, error)
- func (c Conv) Duration(from interface{}) (time.Duration, error)
- func (c Conv) Float32(from interface{}) (float32, error)
- func (c Conv) Float64(from interface{}) (float64, error)
- func (c Conv) Int(from interface{}) (int, error)
- func (c Conv) Int16(from interface{}) (int16, error)
- func (c Conv) Int32(from interface{}) (int32, error)
- func (c Conv) Int64(from interface{}) (int64, error)
- func (c Conv) Int8(from interface{}) (int8, error)
- func (c Conv) Map(into, from interface{}) error
- func (c Conv) Slice(into interface{}, from interface{}) error
- func (c Conv) String(from interface{}) (string, error)
- func (c Conv) Time(from interface{}) (time.Time, error)
- func (c Conv) Uint(from interface{}) (uint, error)
- func (c Conv) Uint16(from interface{}) (uint16, error)
- func (c Conv) Uint32(from interface{}) (uint32, error)
- func (c Conv) Uint64(from interface{}) (uint64, error)
- func (c Conv) Uint8(from interface{}) (uint8, error)
- type Converter
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Bool ¶
func Bool(from interface{}) bool
Bool will convert the given value to a bool, returns the default value of false if a conversion can not be made.
func Duration ¶
Duration will convert the given value to a time.Duration, returns the default value of 0ns if a conversion can not be made.
func Float32 ¶
func Float32(from interface{}) float32
Float32 will convert the given value to a float32, returns the default value of 0.0 if a conversion can not be made.
func Float64 ¶
func Float64(from interface{}) float64
Float64 will convert the given value to a float64, returns the default value of 0.0 if a conversion can not be made.
func Int ¶
func Int(from interface{}) int
Int will convert the given value to a int, returns the default value of 0 if a conversion can not be made.
func Int16 ¶
func Int16(from interface{}) int16
Int16 will convert the given value to a int16, returns the default value of 0 if a conversion can not be made.
func Int32 ¶
func Int32(from interface{}) int32
Int32 will convert the given value to a int32, returns the default value of 0 if a conversion can not be made.
func Int64 ¶
func Int64(from interface{}) int64
Int64 will convert the given value to a int64, returns the default value of 0 if a conversion can not be made.
func Int8 ¶
func Int8(from interface{}) int8
Int8 will convert the given value to a int8, returns the default value of 0 if a conversion can not be made.
func Map ¶
func Map(into, from interface{}) error
Map will perform conversion by inferring the key and element types from the given map. The from element is traversed recursively and the behavior if the value is mutated during iteration is undefined, though at worst an error will be returned as this library will never panic.
An error is returned if the below restrictions are not met:
- It must be a non-pointer, non-nil initialized map
- Both the key and element T must be supported by this library
- The key must be a value T, the element may be a T or *T
Example:
into := make(map[string]int64) err := conv.Map(into, []string{"12", "345", "6789"}) // into -> map[string]int64{"0": 12, "1", 234, "2", 6789}
See examples for more usages.
func Slice ¶
func Slice(into, from interface{}) error
Slice will perform conversion by inferring the element type from the given slice. The from element is traversed recursively and the behavior if the value is mutated during iteration is undefined, though at worst an error will be returned as this library will never panic.
An error is returned if the below restrictions are not met:
- It must be a pointer to a slice, it does not have to be initialized
- The element must be a T or *T of a type supported by this library
Example:
var into []int64 err := conv.Slice(&into, []string{"12", "345", "6789"}) // into -> []int64{12, 234, 6789}
See examples for more usages.
func String ¶
func String(from interface{}) string
String will convert the given value to a string, returns the default value of "" if a conversion can not be made.
func Time ¶
Time will convert the given value to a time.Time, returns the empty struct time.Time{} if a conversion can not be made.
func Uint ¶
func Uint(from interface{}) uint
Uint will convert the given value to a uint, returns the default value of 0 if a conversion can not be made.
func Uint16 ¶
func Uint16(from interface{}) uint16
Uint16 will convert the given value to a uint16, returns the default value of 0 if a conversion can not be made.
func Uint32 ¶
func Uint32(from interface{}) uint32
Uint32 will convert the given value to a uint32, returns the default value of 0 if a conversion can not be made.
Types ¶
type Conv ¶
type Conv struct{}
Conv implements the Converter interface. It does not require initialization or share state and is safe for use by multiple Goroutines.
func (Conv) Bool ¶
Bool attempts to convert the given value to bool, returns the zero value and an error on failure.
func (Conv) Duration ¶
Duration attempts to convert the given value to time.Duration, returns the zero value and an error on failure.
func (Conv) Float32 ¶
Float32 attempts to convert the given value to Float32, returns the zero value and an error on failure.
func (Conv) Float64 ¶
Float64 attempts to convert the given value to float64, returns the zero value and an error on failure.
func (Conv) Int ¶
Int attempts to convert the given value to int, returns the zero value and an error on failure.
func (Conv) Int16 ¶
Int16 attempts to convert the given value to int16, returns the zero value and an error on failure.
func (Conv) Int32 ¶
Int32 attempts to convert the given value to int32, returns the zero value and an error on failure.
func (Conv) Int64 ¶
Int64 attempts to convert the given value to int64, returns the zero value and an error on failure.
func (Conv) Int8 ¶
Int8 attempts to convert the given value to int8, returns the zero value and an error on failure.
func (Conv) Map ¶
Map will perform conversion by inferring the key and element types from the given map and taking values from the given interface.
func (Conv) Slice ¶
Slice will perform conversion by inferring the element type from the given slice and taking values from the given interface.
func (Conv) String ¶
String returns the string representation from the given interface{} value and can not currently fail. Although an error is currently provided only for API cohesion you should still check it to be future proof.
func (Conv) Time ¶
Time attempts to convert the given value to time.Time, returns the zero value of time.Time and an error on failure.
func (Conv) Uint ¶
Uint attempts to convert the given value to uint, returns the zero value and an error on failure.
func (Conv) Uint16 ¶
Uint16 attempts to convert the given value to uint16, returns the zero value and an error on failure.
func (Conv) Uint32 ¶
Uint32 attempts to convert the given value to uint32, returns the zero value and an error on failure.
type Converter ¶
type Converter interface { // Map will perform conversion by inferring the key and element types from the // given map and taking values from the given interface. Map(into, from interface{}) error // Slice will perform conversion by inferring the element type from the given // slice and taking values from the given interface. Slice(into, from interface{}) error // Bool returns the bool representation from the given interface value. // Returns the default value of false and an error on failure. Bool(from interface{}) (to bool, err error) // Duration returns the time.Duration representation from the given // interface{} value. Returns the default value of 0 and an error on failure. Duration(from interface{}) (to time.Duration, err error) // String returns the string representation from the given interface // value and can not fail. An error is provided only for API cohesion. String(from interface{}) (to string, err error) // Time returns the time.Time{} representation from the given interface // value. Returns an empty time.Time struct and an error on failure. Time(from interface{}) (to time.Time, err error) // Float32 returns the float32 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Float32(from interface{}) (to float32, err error) // Float64 returns the float64 representation from the given interface // value. Returns the default value of 0 and an error on failure. Float64(from interface{}) (to float64, err error) // Int returns the int representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Int(from interface{}) (to int, err error) // Int8 returns the int8 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Int8(from interface{}) (to int8, err error) // Int16 returns the int16 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Int16(from interface{}) (to int16, err error) // Int32 returns the int32 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Int32(from interface{}) (to int32, err error) // Int64 returns the int64 representation from the given interface // value. Returns the default value of 0 and an error on failure. Int64(from interface{}) (to int64, err error) // Uint returns the uint representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Uint(from interface{}) (to uint, err error) // Uint8 returns the uint8 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Uint8(from interface{}) (to uint8, err error) // Uint16 returns the uint16 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Uint16(from interface{}) (to uint16, err error) // Uint32 returns the uint32 representation from the given empty interface // value. Returns the default value of 0 and an error on failure. Uint32(from interface{}) (to uint32, err error) // Uint64 returns the uint64 representation from the given interface // value. Returns the default value of 0 and an error on failure. Uint64(from interface{}) (to uint64, err error) }
Converter supports conversion to basic types, that is Boolean, Numeric and Strings. As a special case it may convert to the time.Time structure. It is the primary user facing interface for this library.