pax_global_header00006660000000000000000000000064130057060700014510gustar00rootroot0000000000000052 comment=00c06406c2dd2e011f153a6502a21473676db33f to-1.0.0/000077500000000000000000000000001300570607000121305ustar00rootroot00000000000000to-1.0.0/.travis.yml000066400000000000000000000002461300570607000142430ustar00rootroot00000000000000language: go go: - 1.1 - 1.2 - tip env: - GOARCH=amd64 script: - go version - go get menteslibres.net/gosexy/to - go test menteslibres.net/gosexy/to to-1.0.0/LICENSE000066400000000000000000000021051300570607000131330ustar00rootroot00000000000000Copyright (c) 2012 José Carlos Nieto, http://xiam.menteslibres.org/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. to-1.0.0/README.md000066400000000000000000000112201300570607000134030ustar00rootroot00000000000000# gosexy/to *Convenient* functions for converting values between common Go datatypes. For Go 1.1+. This package ignores errors and allows quick-and-dirty conversions between Go datatypes. When any conversion seems unreasonable a [zero value][3] is used as fallback. If you're not working with human provided data, fuzzy input or if you'd rather not ignore any error in your program, you should better use the standard Go packages for conversion, such as [strconv][4], [fmt][5] or even [standard conversion][6] they may be better suited for the task. [![Build Status](https://travis-ci.org/gosexy/to.png)](https://travis-ci.org/gosexy/to) ## Installation ```sh go get -u menteslibres.net/gosexy/to ``` ## Usage Import the package ```go import "menteslibres.net/gosexy/to" ``` Use the available `to` functions to convert a `float64` into a `string`: ```go // "1.23" s := to.String(1.23) ``` Or a `bool` into `string`: ```go // "true" s := to.String(true) ``` What about the other way around? `string` to `float64` and `string` to `bool`. ```go // 1.23 f := to.Float64("1.23") // true b := to.Bool("true") ``` Note that this package only provides `to.Uint64()`, `to.Int64()` and `to.Float64()` but no `to.Uint8()`, `to.Uint()` or `to.Float32()` functions, if you'd like to produce a `float32` instead of a `float64` you'd first use `to.Float64()` and then cast the output using `float32()`. ```go f32 := float32(to.Float64("12.34")) ``` There is another important function, `to.Convert()` that accepts any value (`interface{}`) as first argument and also a `reflect.Kind`, as second, that defines the data type the first argument will be converted to, this is also the only function that returns an `error` value. ```go val, err := to.Convert("12345", reflect.Int64) ``` Date formats and durations are also handled, you can use many fuzzy date formats and they would be converted into `time.Time` values. ```go timeVal = to.Time("2012-03-24") timeVal = to.Time("Mar 24, 2012") durationVal := to.Duration("12s37ms") ``` Now, an important question: how fast is this library compared to standard methods, like the `fmt` or `strconv` packages? It is, of course, a little slower that `strconv` methods but it is faster than `fmt`, so it provides an acceptable speed for most projects. You can test it by yourself: ```sh $ go test -test.bench=. PASS BenchmarkFmtIntToString 5000000 547 ns/op BenchmarkFmtFloatToString 2000000 914 ns/op BenchmarkStrconvIntToString 10000000 142 ns/op BenchmarkStrconvFloatToString 1000000 1155 ns/op BenchmarkIntToString 10000000 325 ns/op BenchmarkFloatToString 2000000 873 ns/op BenchmarkIntToBytes 10000000 198 ns/op BenchmarkBoolToString 50000000 48.0 ns/op BenchmarkFloatToBytes 2000000 773 ns/op BenchmarkIntToBool 5000000 403 ns/op BenchmarkStringToTime 1000000 1063 ns/op BenchmarkConvert 10000000 199 ns/op ok menteslibres.net/gosexy/to 27.670s ``` See the [docs][1] for a full reference of all the available `to` methods. ## License This is Open Source released under the terms of the MIT License: > Copyright (c) 2013-2014 José Carlos Nieto, https://menteslibres.net/xiam > > Permission is hereby granted, free of charge, to any person obtaining > a copy of this software and associated documentation files (the > "Software"), to deal in the Software without restriction, including > without limitation the rights to use, copy, modify, merge, publish, > distribute, sublicense, and/or sell copies of the Software, and to > permit persons to whom the Software is furnished to do so, subject to > the following conditions: > > The above copyright notice and this permission notice shall be > included in all copies or substantial portions of the Software. > > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE > LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [1]: http://godoc.org/menteslibres.net/gosexy/to [2]: https://menteslibres.net/gosexy/to [3]: http://golang.org/ref/spec#The_zero_value [4]: http://golang.org/pkg/strconv/ [5]: http://golang.org/pkg/fmt/ [6]: http://golang.org/ref/spec#Conversions to-1.0.0/as.go000066400000000000000000000027011300570607000130620ustar00rootroot00000000000000package to import "time" // AsBool converts v to bool or returns false. func AsBool(v interface{}) bool { b, err := Bool(v) if err != nil { return false } return b } // AsDuration converts v to Duration or returns Duration(0). func AsDuration(v interface{}) time.Duration { d, err := Duration(v) if err != nil { return time.Duration(0) } return d } // AsInt converts v to int or returns 0. func AsInt(v interface{}) int { i, err := Int64(v) if err != nil { return 0 } return int(i) } // AsInt64 converts v to int64 or returns 0. func AsInt64(v interface{}) int64 { i, err := Int64(v) if err != nil { return 0 } return i } // AsFloat converts v to float64 or returns float64(0) func AsFloat(v interface{}) float64 { f, err := Float64(v) if err != nil { return 0 } return f } // AsMap converts v to map[string]interface{} or returns val. func AsMap(v interface{}) map[string]interface{} { m, err := Map(v) if err != nil { return map[string]interface{}{} } return m } // AsSlice converts v to []interface{} or returns val. func AsSlice(v interface{}, val []interface{}) []interface{} { sli, err := Slice(v) if err != nil { return []interface{}{} } return sli } // AsString converts v to string or returns "" func AsString(v interface{}) string { return String(v) } // AsTime converts v to Time or returns Time{} func AsTime(v interface{}) time.Time { t, err := Time(v) if err != nil { return time.Time{} } return t } to-1.0.0/deprecated.go000066400000000000000000000027471300570607000145710ustar00rootroot00000000000000package to import "time" // ZeroBool converts v to bool or returns false. func ZeroBool(v interface{}) bool { b, err := Bool(v) if err != nil { return false } return b } // ZeroDuration converts v to Duration or returns Duration(0). func ZeroDuration(v interface{}) time.Duration { d, err := Duration(v) if err != nil { return time.Duration(0) } return d } // ZeroInt converts v to int64 or returns 0. func ZeroInt(v interface{}) int { i, err := Int64(v) if err != nil { return 0 } return int(i) } // ZeroInt64 converts v to int64 or returns 0. func ZeroInt64(v interface{}) int64 { i, err := Int64(v) if err != nil { return 0 } return i } // ZeroFloat converts v to float64 or returns float64(0) func ZeroFloat(v interface{}) float64 { f, err := Float64(v) if err != nil { return 0 } return f } // ZeroMap converts v to map[string]interface{} or returns val. func ZeroMap(v interface{}) map[string]interface{} { m, err := Map(v) if err != nil { return map[string]interface{}{} } return m } // ZeroSlice converts v to []interface{} or returns val. func ZeroSlice(v interface{}, val []interface{}) []interface{} { sli, err := Slice(v) if err != nil { return []interface{}{} } return sli } // ZeroString converts v to string or returns "" func ZeroString(v interface{}) string { return String(v) } // ZeroTime converts v to Time or returns Time{} func ZeroTime(v interface{}) time.Time { t, err := Time(v) if err != nil { return time.Time{} } return t } to-1.0.0/must.go000066400000000000000000000026311300570607000134510ustar00rootroot00000000000000package to import "time" // MustBool converts v to bool or panics. func MustBool(v interface{}) bool { b, err := Bool(v) if err != nil { panic(err) } return b } // MustDuration converts v to Duration or panics. func MustDuration(v interface{}) time.Duration { d, err := Duration(v) if err != nil { panic(err) } return d } // MustInt convert v to int64 or panics. func MustInt(v interface{}) int { i, err := Int64(v) if err != nil { panic(err) } return int(i) } // MustInt64 convert v to int64 or panics. func MustInt64(v interface{}) int64 { i, err := Int64(v) if err != nil { panic(err) } return i } // MustFloat converts v to float64 or panics. func MustFloat(v interface{}) float64 { f, err := Float64(v) if err != nil { panic(err) } return f } // MustMap converts v to map[string]interface{} or returns val. func MustMap(v interface{}, val map[string]interface{}) map[string]interface{} { m, err := Map(v) if err != nil { panic(err) } return m } // MustSlice converts v to []interface{} or returns val. func MustSlice(v interface{}, val []interface{}) []interface{} { sli, err := Slice(v) if err != nil { panic(err) } return sli } // MustString converts v to iterface{} func MustString(v interface{}) string { return String(v) } // MustTime converts v to Time or panics. func MustTime(v interface{}) time.Time { t, err := Time(v) if err != nil { panic(err) } return t } to-1.0.0/or.go000066400000000000000000000027561300570607000131110ustar00rootroot00000000000000package to import "time" // OrBool converts v to bool or returns val. func OrBool(v interface{}, val bool) bool { b, err := Bool(v) if err != nil { return val } return b } // OrDuration converts v to Duration or returns val. func OrDuration(v interface{}, val time.Duration) time.Duration { d, err := Duration(v) if err != nil { return val } return d } // OrInt converts v to int64 or returns val. func OrInt(v interface{}, val int) int { i, err := Int64(v) if err != nil { return val } return int(i) } // OrInt64 converts v to int64 or returns val. func OrInt64(v interface{}, val int64) int64 { i, err := Int64(v) if err != nil { return val } return i } // OrFloat converts v to float64 or returns val. func OrFloat(v interface{}, val float64) float64 { f, err := Float64(v) if err != nil { return val } return f } // OrMap converts v to map[string]interface{} or returns val. func OrMap(v interface{}, val map[string]interface{}) map[string]interface{} { m, err := Map(v) if err != nil { return val } return m } // OrSlice converts v to []interface{} or returns val. func OrSlice(v interface{}, val []interface{}) []interface{} { sli, err := Slice(v) if err != nil { return val } return sli } // OrString converts v to string or returns "" func OrString(v interface{}) string { return String(v) } // OrTime converts v to Time or returns Time{} func OrTime(v interface{}, val time.Time) time.Time { t, err := Time(v) if err != nil { return val } return t } to-1.0.0/to.go000066400000000000000000000355451300570607000131150ustar00rootroot00000000000000/* Copyright (c) 2012-2013 José Carlos Nieto, http://xiam.menteslibres.org/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*Package to is a helper package for converting between datatypes. If a certain value can not be directly converted to another, the zero value of the destination type is returned instead. */ package to import ( "fmt" "reflect" "regexp" "strconv" "time" ) var ( durationType = reflect.TypeOf(time.Duration(0)) timeType = reflect.TypeOf(time.Time{}) ) const ( digits = "0123456789" uintbuflen = 20 ) const ( // KindTime is reserved for Time kind. KindTime reflect.Kind = iota + 1000000000 // KindDuration is reserved for Duration kind. KindDuration ) var strToTimeFormats = []string{ "2006-01-02 15:04:05 Z0700 MST", "2006-01-02 15:04:05 Z07:00 MST", "2006-01-02 15:04:05 Z0700 -0700", "Mon Jan _2 15:04:05 -0700 MST 2006", time.RFC822Z, // "02 Jan 06 15:04 -0700" time.RFC3339, // "2006-01-02T15:04:05Z07:00", RFC3339Nano "2006-01-02 15:04:05 -0700", "2006-01-02 15:04:05 Z07:00", time.RubyDate, // "Mon Jan 02 15:04:05 -0700 2006" time.RFC1123Z, // "Mon, 02 Jan 2006 15:04:05 -0700" time.RFC822, // "02 Jan 06 15:04 MST", "2006-01-02 15:04:05 MST", time.UnixDate, // "Mon Jan _2 15:04:05 MST 2006", time.RFC1123, // "Mon, 02 Jan 2006 15:04:05 MST", time.RFC850, // "Monday, 02-Jan-06 15:04:05 MST", time.Kitchen, // "3:04PM" "01/02/06", "2006-01-02", "2006/01/02", "01/02/2006", "Jan _2, 2006", "01/02/06 15:04", time.Stamp, // "Jan _2 15:04:05", time.StampMilli, time.StampMicro, time.StampNano, time.ANSIC, // "Mon Jan _2 15:04:05 2006" "2006-01-02 15:04", "2006-01-02T15:04", "01/02/2006 15:04", "01/02/06 15:04:05", "01/02/2006 15:04:05", "2006-01-02 15:04:05", "2006-01-02T15:04:05", "_2/Jan/2006 15:04:05", } var strToDurationMatches = map[*regexp.Regexp]func([][][]byte) (time.Duration, error){ regexp.MustCompile(`^(\-?\d+):(\d+)$`): func(m [][][]byte) (time.Duration, error) { sign := 1 i64, err := Int64(m[0][1]) if err != nil { return time.Duration(0), err } hrs := time.Hour * time.Duration(i64) if hrs < 0 { hrs = -1 * hrs sign = -1 } i64, err = Int64(m[0][2]) if err != nil { return time.Duration(0), err } min := time.Minute * time.Duration(i64) return time.Duration(sign) * (hrs + min), nil }, regexp.MustCompile(`^(\-?\d+):(\d+):(\d+)$`): func(m [][][]byte) (time.Duration, error) { sign := 1 i64, err := Int64(m[0][1]) if err != nil { return time.Duration(0), err } hrs := time.Hour * time.Duration(i64) if hrs < 0 { hrs = -1 * hrs sign = -1 } i64, err = Int64(m[0][2]) if err != nil { return time.Duration(0), err } min := time.Minute * time.Duration(i64) i64, err = Int64(m[0][3]) if err != nil { return time.Duration(0), err } sec := time.Second * time.Duration(i64) return time.Duration(sign) * (hrs + min + sec), nil }, regexp.MustCompile(`^(\-?\d+):(\d+):(\d+).(\d+)$`): func(m [][][]byte) (time.Duration, error) { sign := 1 i64, err := Int64(m[0][1]) if err != nil { return time.Duration(0), err } hrs := time.Hour * time.Duration(i64) if hrs < 0 { hrs = -1 * hrs sign = -1 } i64, err = Int64(m[0][2]) if err != nil { return time.Duration(0), err } min := time.Minute * time.Duration(i64) i64, err = Int64(m[0][3]) if err != nil { return time.Duration(0), err } sec := time.Second * time.Duration(i64) lst := m[0][4] for len(lst) < 9 { lst = append(lst, '0') } lst = lst[0:9] i64, err = Int64(lst) if err != nil { return time.Duration(0), err } return time.Duration(sign) * (hrs + min + sec + time.Duration(i64)), nil }, } func strToDuration(v string) (time.Duration, error) { var err error var d time.Duration d, err = time.ParseDuration(v) if err == nil { return d, nil } b := []byte(v) for re, fn := range strToDurationMatches { m := re.FindAllSubmatch(b, -1) if m != nil { return fn(m) } } return time.Duration(0), fmt.Errorf("Could not convert %q to Duration", v) } func uint64ToBytes(v uint64) []byte { buf := make([]byte, uintbuflen) i := len(buf) for v >= 10 { i-- buf[i] = digits[v%10] v = v / 10 } i-- buf[i] = digits[v%10] return buf[i:] } func int64ToBytes(v int64) []byte { negative := false if v < 0 { negative = true v = -v } uv := uint64(v) buf := uint64ToBytes(uv) if negative { buf2 := []byte{'-'} buf2 = append(buf2, buf...) return buf2 } return buf } func float32ToBytes(v float32) []byte { slice := strconv.AppendFloat(nil, float64(v), 'g', -1, 32) return slice } func float64ToBytes(v float64) []byte { slice := strconv.AppendFloat(nil, v, 'g', -1, 64) return slice } func complex128ToBytes(v complex128) []byte { buf := []byte{'('} r := strconv.AppendFloat(buf, real(v), 'g', -1, 64) im := imag(v) if im >= 0 { buf = append(r, '+') } else { buf = r } i := strconv.AppendFloat(buf, im, 'g', -1, 64) buf = append(i, []byte{'i', ')'}...) return buf } // Time converts a date string into a time.Time value, several date formats are tried. func Time(val interface{}) (time.Time, error) { s := String(val) for _, format := range strToTimeFormats { r, err := time.ParseInLocation(format, s, time.Local) if err == nil { return r, nil } } return time.Time{}, fmt.Errorf("Could not convert %q to Time", val) } // Duration tries to convert the argument into a time.Duration value. Returns // time.Duration(0) if any error occurs. func Duration(val interface{}) (time.Duration, error) { switch t := val.(type) { case int: return time.Duration(int64(t)), nil case int8: return time.Duration(int64(t)), nil case int16: return time.Duration(int64(t)), nil case int32: return time.Duration(int64(t)), nil case int64: return time.Duration(t), nil case uint: return time.Duration(int64(t)), nil case uint8: return time.Duration(int64(t)), nil case uint16: return time.Duration(int64(t)), nil case uint32: return time.Duration(int64(t)), nil case uint64: return time.Duration(int64(t)), nil } return strToDuration(String(val)) } // Bytes tries to convert the argument into a []byte array. Returns []byte{} if any // error occurs. func Bytes(val interface{}) []byte { if val == nil { return []byte{} } switch t := val.(type) { case int: return int64ToBytes(int64(t)) case int8: return int64ToBytes(int64(t)) case int16: return int64ToBytes(int64(t)) case int32: return int64ToBytes(int64(t)) case int64: return int64ToBytes(int64(t)) case uint: return uint64ToBytes(uint64(t)) case uint8: return uint64ToBytes(uint64(t)) case uint16: return uint64ToBytes(uint64(t)) case uint32: return uint64ToBytes(uint64(t)) case uint64: return uint64ToBytes(uint64(t)) case float32: return float32ToBytes(t) case float64: return float64ToBytes(t) case complex128: return complex128ToBytes(t) case complex64: return complex128ToBytes(complex128(t)) case bool: if t == true { return []byte("true") } return []byte("false") case string: return []byte(t) case []byte: return t } return []byte(fmt.Sprintf("%v", val)) } // String tries to convert the argument into a string. Returns "" if any error occurs. func String(val interface{}) string { if val == nil { return "" } switch t := val.(type) { case int: return strconv.Itoa(t) case int8: return strconv.FormatInt(int64(t), 10) case int16: return strconv.FormatInt(int64(t), 10) case int32: return strconv.FormatInt(int64(t), 10) case int64: return strconv.FormatInt(t, 10) case uint: return strconv.FormatUint(uint64(t), 10) case uint8: return strconv.FormatUint(uint64(t), 10) case uint16: return strconv.FormatUint(uint64(t), 10) case uint32: return strconv.FormatUint(uint64(t), 10) case uint64: return strconv.FormatUint(t, 10) case float32: return strconv.FormatFloat(float64(t), 'g', -1, 32) case float64: return strconv.FormatFloat(t, 'g', -1, 64) case complex128: return string(complex128ToBytes(t)) case complex64: return string(complex128ToBytes(complex128(t))) case bool: if t { return "true" } return "false" case string: return t case []byte: return string(t) } return fmt.Sprintf("%v", val) } // Slice ... func Slice(val interface{}) ([]interface{}, error) { if si, ok := val.([]interface{}); ok { return si, nil } list := []interface{}{} if val == nil { return list, nil } switch reflect.TypeOf(val).Kind() { default: return nil, fmt.Errorf("Could not convert %q to Slice", val) case reflect.Slice: vval := reflect.ValueOf(val) size := vval.Len() list := make([]interface{}, size) vlist := reflect.ValueOf(list) for i := 0; i < size; i++ { vlist.Index(i).Set(vval.Index(i)) } return list, nil } } // Map ... func Map(val interface{}) (map[string]interface{}, error) { if msi, ok := val.(map[string]interface{}); ok { return msi, nil } m := map[string]interface{}{} if val == nil { return m, nil } switch reflect.TypeOf(val).Kind() { default: return nil, fmt.Errorf("Could not convert %q to Map", val) case reflect.Map: vval := reflect.ValueOf(val) vlist := reflect.ValueOf(m) for _, vkey := range vval.MapKeys() { key := String(vkey.Interface()) vlist.SetMapIndex(reflect.ValueOf(key), vval.MapIndex(vkey)) } return m, nil } } // Int64 tries to convert the argument into an int64. Returns int64(0) if any error // occurs. func Int64(val interface{}) (int64, error) { switch t := val.(type) { case int: return int64(t), nil case int8: return int64(t), nil case int16: return int64(t), nil case int32: return int64(t), nil case int64: return int64(t), nil case uint: return int64(t), nil case uint8: return int64(t), nil case uint16: return int64(t), nil case uint32: return int64(t), nil case uint64: return int64(t), nil case bool: if t == true { return int64(1), nil } return int64(0), nil case float32: return int64(t), nil case float64: return int64(t), nil case string: return strconv.ParseInt(t, 10, 64) case []byte: return strconv.ParseInt(string(t), 10, 64) } return 0, fmt.Errorf("Could not convert %q to int64 %T", val, val) } // Uint64 tries to convert the argument into an uint64. Returns uint64(0) if any error // occurs. func Uint64(val interface{}) (uint64, error) { switch t := val.(type) { case int: return uint64(t), nil case int8: return uint64(t), nil case int16: return uint64(t), nil case int32: return uint64(t), nil case int64: return uint64(t), nil case uint: return uint64(t), nil case uint8: return uint64(t), nil case uint16: return uint64(t), nil case uint32: return uint64(t), nil case uint64: return uint64(t), nil case float32: return uint64(t), nil case float64: return uint64(t), nil case bool: if t == true { return uint64(1), nil } return uint64(0), nil case string: return strconv.ParseUint(t, 10, 64) } return 0, fmt.Errorf("Could not convert %q to uint64", val) } // Float64 tries to convert the argument into a float64. Returns float64(0.0) if any // error occurs. func Float64(val interface{}) (float64, error) { switch t := val.(type) { case int: return float64(t), nil case int8: return float64(t), nil case int16: return float64(t), nil case int32: return float64(t), nil case int64: return float64(t), nil case uint: return float64(t), nil case uint8: return float64(t), nil case uint16: return float64(t), nil case uint32: return float64(t), nil case uint64: return float64(t), nil case float32: return float64(t), nil case float64: return float64(t), nil case bool: if t == true { return float64(1), nil } return float64(0), nil case string: return strconv.ParseFloat(val.(string), 64) default: return 0, fmt.Errorf("Inconvertible float type %T", t) } } // Bool tries to convert the argument into a bool. Returns false if any error occurs. func Bool(value interface{}) (bool, error) { s := String(value) return strconv.ParseBool(s) } // Convert tries to convert the argument into a reflect.Kind element. func Convert(value interface{}, t reflect.Kind) (interface{}, error) { switch reflect.TypeOf(value).Kind() { case reflect.Slice: switch t { case reflect.String: if reflect.TypeOf(value).Elem().Kind() == reflect.Uint8 { return string(value.([]byte)), nil } return String(value), nil case reflect.Slice: default: return nil, fmt.Errorf("Could not convert slice into non-slice.") } case reflect.String: switch t { case reflect.Slice: return Bytes(value), nil } } switch t { case reflect.String: return String(value), nil case reflect.Uint64: return Uint64(value) case reflect.Uint32: u, err := Uint64(value) if err != nil { return 0, err } return uint32(u), nil case reflect.Uint16: u, err := Uint64(value) if err != nil { return 0, err } return uint16(u), nil case reflect.Uint8: u, err := Uint64(value) if err != nil { return 0, err } return uint8(u), nil case reflect.Uint: u, err := Uint64(value) if err != nil { return 0, err } return uint(u), nil case reflect.Int64: return Int64(value) case reflect.Int32: u, err := Int64(value) if err != nil { return 0, err } return int32(u), nil case reflect.Int16: u, err := Int64(value) if err != nil { return 0, err } return int16(u), nil case reflect.Int8: u, err := Int64(value) if err != nil { return 0, err } return int8(u), nil case reflect.Int: u, err := Int64(value) if err != nil { return 0, err } return int(u), nil case reflect.Float64: return Float64(value) case reflect.Float32: f, err := Float64(value) if err != nil { return 0, err } return float32(f), nil case reflect.Bool: return Bool(value) case reflect.Interface: return value, nil case KindTime: return Time(value) case KindDuration: return Duration(value) } return nil, fmt.Errorf("Could not convert %s into %s.", reflect.TypeOf(value).Kind(), t) } to-1.0.0/to_test.go000066400000000000000000000256111300570607000141450ustar00rootroot00000000000000/* Copyright (c) 2012-2013 José Carlos Nieto, http://xiam.menteslibres.org/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package to import ( "bytes" "fmt" "reflect" "strconv" "testing" "time" ) func TestToString(t *testing.T) { if String(0) != "0" { t.Fatalf("Test failed.") } if String(-0) != "0" { t.Fatalf("Test failed.") } if String(1) != "1" { t.Fatalf("Test failed.") } if String(-1) != "-1" { t.Fatalf("Test failed.") } if String(10) != "10" { t.Fatalf("Test failed.") } if String(-10) != "-10" { t.Fatalf("Test failed.") } if String(int64(9223372036854775807)) != "9223372036854775807" { t.Fatalf("Test failed.") } if String(int64(-9223372036854775807)) != "-9223372036854775807" { t.Fatalf("Test failed.") } if String(uint64(18446744073709551615)) != "18446744073709551615" { t.Fatalf("Test failed.") } } func TestToBytes(t *testing.T) { if string(Bytes(0)) != "0" { t.Fatalf("Test failed.") } if string(Bytes(-0)) != "0" { t.Fatalf("Test failed.") } if string(Bytes(1)) != "1" { t.Fatalf("Test failed.") } if string(Bytes(-1)) != "-1" { t.Fatalf("Test failed.") } if string(Bytes(10)) != "10" { t.Fatalf("Test failed.") } if string(Bytes(-10)) != "-10" { t.Fatalf("Test failed.") } if string(Bytes(int64(9223372036854775807))) != "9223372036854775807" { t.Fatalf("Test failed.") } if string(Bytes(int64(-9223372036854775807))) != "-9223372036854775807" { t.Fatalf("Test failed.") } if string(Bytes(uint64(18446744073709551615))) != "18446744073709551615" { t.Fatalf("Test failed.") } } func TestFloating(t *testing.T) { if String(float32(1.1)) != "1.1" { t.Fatalf("Test failed.") } if String(float32(-1.1)) != "-1.1" { t.Fatalf("Test failed.") } if String(12345.12345) != "12345.12345" { t.Fatalf("Test failed.") } if String(-12345.12345) != "-12345.12345" { t.Fatalf("Test failed.") } if String(float64(-12345.12345)) != "-12345.12345" { t.Fatalf("Test failed.") } } func TestComplex(t *testing.T) { if String(complex(1, 1)) != "(1+1i)" { t.Fatalf("Test failed.") } if String(complex(1, -1)) != "(1-1i)" { t.Fatalf("Test failed.") } if String(complex(-1, -1)) != "(-1-1i)" { t.Fatalf("Test failed.") } if String(complex(-1, 1)) != "(-1+1i)" { t.Fatalf("Test failed.") } if String(true) != "true" { t.Fatalf("Test failed.") } if String(false) != "false" { t.Fatalf("Test failed.") } if String("hello") != "hello" { t.Fatalf("Test failed.") } } func TestNil(t *testing.T) { if String(nil) != "" { t.Fatalf("Test failed.") } } func TestBytes(t *testing.T) { if String([]byte{'h', 'e', 'l', 'l', 'o'}) != "hello" { t.Fatalf("Test failed.") } } func TestIntegers(t *testing.T) { if i, _ := Int64(1); i != int64(1) { t.Fatalf("Test failed.") } if i, _ := Int64(-1); i != int64(-1) { t.Fatalf("Test failed.") } if i, _ := Int64(true); int32(i) != int32(1) { t.Fatalf("Test failed.") } if i, _ := Int64(false); int32(i) != int32(0) { t.Fatalf("Test failed.") } if i, _ := Int64("123"); int32(i) != int32(123) { t.Fatalf("Test failed.") } if u, _ := Uint64("123"); uint32(u) != uint32(123) { t.Fatalf("Test failed.") } if u, _ := Uint64("0"); uint32(u) != uint32(0) { t.Fatalf("Test failed.") } if u, _ := Uint64(5); uint(u) != uint(5) { t.Fatalf("Test failed.") } if u, _ := Uint64(5.1); uint(u) != uint(5) { t.Fatalf("Test failed.") } if u, _ := Uint64(6.1); int8(u) != int8(6) { t.Fatalf("Test failed.") } } func TestFloat(t *testing.T) { if f, _ := Float64(1); float32(f) != float32(1) { t.Fatalf("Test failed.") } if f, _ := Float64(1.2); float32(f) != float32(1.2) { t.Fatalf("Test failed.") } if f, _ := Float64(-11.2); float64(f) != float64(-11.2) { t.Fatalf("Test failed.") } if f, _ := Float64("-11.2"); float64(f) != float64(-11.2) { t.Fatalf("Test failed.") } } func TestBool(t *testing.T) { if b, e := Bool("t"); e != nil || b != true { t.Fatalf("Test failed.") } if b, e := Bool("FALSE"); e != nil || b != false { t.Fatalf("Test failed.") } if b, e := Bool("0"); e != nil || b != false { t.Fatalf("Test failed.") } if b, e := Bool("1"); e != nil || b != true { t.Fatalf("Test failed.") } if b, e := Bool(1); e != nil || b != true { t.Fatalf("Test failed.") } } /* // Delayed until Go 1.1 func TestList(t *testing.T) { mylist := []string{ "a", "b", "c", "d", "e", } res := List(mylist) if res[2].(string) != "c" { t.Fatalf("Test failed.") } mylist1 := []int{ 1, 2, 3, 4, 5, } res1 := List(mylist1) if res1[2].(int) != 3 { t.Fatalf("Test failed.") } mylist2 := []interface{}{ 1, 2, 3, 4, 5, } res2 := List(mylist2) if res2[2].(int) != 3 { t.Fatalf("Test failed.") } } // Delayed until Go 1.1 func TestMap(t *testing.T) { mymap := map[int]string{ 1: "a", 2: "b", 3: "c", 4: "d", 5: "e", } res := Map(mymap) if res["3"].(string) != "c" { t.Fatalf("Test failed.") } } */ func TestConvert(t *testing.T) { b, _ := Convert(1, reflect.Bool) if b.(bool) != true { t.Fatalf("Test failed.") } i, _ := Convert("456", reflect.Int64) if i.(int64) != int64(456) { t.Fatalf("Test failed.") } i, _ = Convert("0", reflect.Int64) if i.(int64) != int64(0) { t.Fatalf("Test failed.") } ui, _ := Convert("456", reflect.Uint64) if ui.(uint64) != uint64(456) { t.Fatalf("Test failed.") } ui, _ = Convert("0", reflect.Uint64) if ui.(uint64) != uint64(0) { t.Fatalf("Test failed.") } var err error var bs interface{} if bs, err = Convert("string", reflect.Slice); err != nil { t.Fatal(err) } if bytes.Equal(bs.([]byte), []byte("string")) != true { t.Fatalf("Test failed.") } } func TestTimeDuration(t *testing.T) { if d, _ := Duration(123); d != time.Duration(123) { t.Fatalf("Test failed.") } if d, _ := Duration("12s37ms"); d != time.Second*12+time.Millisecond*37 { t.Fatalf("Test failed.") } if d, _ := Duration("13:37"); d != time.Hour*13+time.Minute*37 { t.Fatalf("Test failed.") } if d, _ := Duration("-13:37"); d != -(time.Hour*13 + time.Minute*37) { t.Fatalf("Test failed.") } if d, _ := Duration("13:37:21"); d != time.Hour*13+time.Minute*37+time.Second*21 { t.Fatalf("Test failed.") } if d, _ := Duration("13:37:21.456123"); d != time.Hour*13+time.Minute*37+time.Second*21+time.Microsecond*456123 { t.Fatalf("Test failed.") } if d, _ := Duration("13:37:21.4561231"); d != time.Hour*13+time.Minute*37+time.Second*21+456123100 { t.Fatalf("Test failed.") } if d, _ := Duration("13:37:21.456123789"); d != time.Hour*13+time.Minute*37+time.Second*21+time.Nanosecond*456123789 { t.Fatalf("Test failed.") } if d, _ := Duration("13:37:21.456123789999"); d != time.Hour*13+time.Minute*37+time.Second*21+time.Nanosecond*456123789 { t.Fatalf("Test failed.") } if d, _ := Duration("-13:37:21.456123789999"); d != -(time.Hour*13 + time.Minute*37 + time.Second*21 + time.Nanosecond*456123789) { t.Fatalf("Test failed.") } if _, err := Duration("abc"); err == nil { t.Fatalf("Test failed.") } } func TestDate(t *testing.T) { if tt, _ := Time("2012-03-24"); time.Date(2012, 3, 24, 0, 0, 0, 0, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("2012/03/24"); time.Date(2012, 3, 24, 0, 0, 0, 0, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("2012-03-24 23:13:37"); time.Date(2012, 3, 24, 23, 13, 37, 0, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("2012-03-24 23:13:37.000000123"); time.Date(2012, 3, 24, 23, 13, 37, 123, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("03/24/2012 23:13:37"); time.Date(2012, 3, 24, 23, 13, 37, 0, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("03/24/12 23:13:37.000000123"); time.Date(2012, 3, 24, 23, 13, 37, 123, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("24/Mar/2012 23:13:37"); time.Date(2012, 3, 24, 23, 13, 37, 0, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("Mar 24, 2012"); time.Date(2012, 3, 24, 0, 0, 0, 0, time.Local).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("2012-03-24T23:13:37.123Z"); time.Date(2012, 3, 24, 23, 13, 37, 123000000, time.UTC).Equal(tt) != true { t.Fatalf("Test failed.") } if tt, _ := Time("2012-03-24T23:13:37.123456789Z"); time.Date(2012, 3, 24, 23, 13, 37, 123456789, time.UTC).Equal(tt) != true { t.Fatalf("Test failed.") } if _, err := Time("abc"); err == nil { t.Fatalf("Test failed.") } } func BenchmarkFmtIntToString(b *testing.B) { for i := 0; i < b.N; i++ { fmt.Sprintf("%d", 1) } } func BenchmarkFmtFloatToString(b *testing.B) { for i := 0; i < b.N; i++ { fmt.Sprintf("%f", 1.1) } } func BenchmarkStrconvIntToString(b *testing.B) { for i := 0; i < b.N; i++ { strconv.Itoa(1) } } func BenchmarkStrconvFloatToString(b *testing.B) { for i := 0; i < b.N; i++ { strconv.FormatFloat(1.1, 'g', -1, 64) } } func BenchmarkIntToString(b *testing.B) { for i := 0; i < b.N; i++ { String(1) } } func BenchmarkFloatToString(b *testing.B) { for i := 0; i < b.N; i++ { String(1.1) } } func BenchmarkIntToBytes(b *testing.B) { for i := 0; i < b.N; i++ { Bytes(1) } } func BenchmarkBoolToString(b *testing.B) { for i := 0; i < b.N; i++ { String(true) } } func BenchmarkFloatToBytes(b *testing.B) { for i := 0; i < b.N; i++ { Bytes(1.1) } } func BenchmarkIntToBool(b *testing.B) { for i := 0; i < b.N; i++ { Bool(1) } } func BenchmarkStringToTime(b *testing.B) { for i := 0; i < b.N; i++ { Time("2012-03-24") } } /* func BenchmarkMap(b *testing.B) { mymap := map[int]string{ 1: "a", 2: "b", 3: "c", 4: "d", 5: "e", } for i := 0; i < b.N; i++ { Map(mymap) } } func BenchmarkList(b *testing.B) { mylist := []string{ "a", "b", "c", "d", "e", } for i := 0; i < b.N; i++ { List(mylist) } } */ func BenchmarkConvert(b *testing.B) { for i := 0; i < b.N; i++ { _, err := Convert("567", reflect.Int64) if err != nil { b.Fatalf("Test failed.") return } } }