Writing the README. Handling a few more cases, adding more tests.
This commit is contained in:
parent
6796452c69
commit
559d57776b
70
README.md
70
README.md
@ -1,4 +1,72 @@
|
|||||||
cast
|
cast
|
||||||
====
|
====
|
||||||
|
|
||||||
easy casting from one type to another in Go
|
Easy and safe casting from one type to another in Go
|
||||||
|
|
||||||
|
Don’t Panic! ... Cast
|
||||||
|
|
||||||
|
## What is Cast?
|
||||||
|
|
||||||
|
Cast is a library to convert between different go types in a consistent and easy way.
|
||||||
|
|
||||||
|
Cast provides simple functions to easily convert a number to a string, an
|
||||||
|
interface into a bool, etc. Cast does this intelligently when an obvious
|
||||||
|
conversion is possible. It doesn’t make any attempts to guess what you meant,
|
||||||
|
for example you can only convert a string to an int when it is a string
|
||||||
|
representation of an int such as “8”. Cast was developed for use in
|
||||||
|
[Hugo](http://hugo.spf13.com), a website engine which uses YAML, TOML or JSON
|
||||||
|
for meta data.
|
||||||
|
|
||||||
|
## Why use Cast?
|
||||||
|
|
||||||
|
When working with dynamic data in Go you often need to cast or convert the data
|
||||||
|
from one type into another. Cast goes beyond just using type assertion (though
|
||||||
|
it uses that when possible) to provide a very straightforward and convenient
|
||||||
|
library.
|
||||||
|
|
||||||
|
If you are working with interfaces to handle things like dynamic content
|
||||||
|
you’ll need an easy way to convert an interface into a given type. This
|
||||||
|
is the library for you.
|
||||||
|
|
||||||
|
If you are taking in data from YAML, TOML or JSON or other formats which lack
|
||||||
|
full types, then Cast is the library for you.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Cast provides a handful of To_____ methods. These methods will always return
|
||||||
|
the desired type. **If input is provided that will not convert to that type, the
|
||||||
|
0 or nil value for that type will be returned**.
|
||||||
|
|
||||||
|
Cast also provides identical methods To_____E. These return the same result as
|
||||||
|
the To_____ methods, plus an additional bool which tells you if it successfully
|
||||||
|
converted. Using these methods you can tell the difference between when the
|
||||||
|
input matched the zero value or when the conversion failed and the zero value
|
||||||
|
was returned.
|
||||||
|
|
||||||
|
The following examples are merely a sample of what is available. Please review
|
||||||
|
the code for a complete set.
|
||||||
|
|
||||||
|
### Example ‘ToString’:
|
||||||
|
|
||||||
|
cast.ToString("mayonegg") // "mayonegg"
|
||||||
|
cast.ToString(8) // "8"
|
||||||
|
cast.ToString(8.31) // "8.31"
|
||||||
|
cast.ToString([]byte("one time")) // "one time"
|
||||||
|
cast.ToString(nil) // ""
|
||||||
|
|
||||||
|
var foo interface{} = "one more time"
|
||||||
|
cast.ToString(foo) // "one more time"
|
||||||
|
|
||||||
|
|
||||||
|
### Example ‘ToInt’:
|
||||||
|
|
||||||
|
cast.ToInt(8) // 8
|
||||||
|
cast.ToInt(8.31) // 8
|
||||||
|
cast.ToInt("8") // 8
|
||||||
|
cast.ToInt(true) // 1
|
||||||
|
cast.ToInt(false) // 0
|
||||||
|
|
||||||
|
var eight interface{} = 8
|
||||||
|
cast.ToInt(eight) // 8
|
||||||
|
cast.ToInt(nil) // 0
|
||||||
|
|
||||||
|
10
cast_test.go
10
cast_test.go
@ -14,12 +14,22 @@ import (
|
|||||||
func TestToInt(t *testing.T) {
|
func TestToInt(t *testing.T) {
|
||||||
var eight interface{} = 8
|
var eight interface{} = 8
|
||||||
assert.Equal(t, ToInt(8), 8)
|
assert.Equal(t, ToInt(8), 8)
|
||||||
|
assert.Equal(t, ToInt(8.31), 8)
|
||||||
assert.Equal(t, ToInt("8"), 8)
|
assert.Equal(t, ToInt("8"), 8)
|
||||||
assert.Equal(t, ToInt(true), 1)
|
assert.Equal(t, ToInt(true), 1)
|
||||||
assert.Equal(t, ToInt(false), 0)
|
assert.Equal(t, ToInt(false), 0)
|
||||||
assert.Equal(t, ToInt(eight), 8)
|
assert.Equal(t, ToInt(eight), 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestToString(t *testing.T) {
|
||||||
|
var foo interface{} = "one more time"
|
||||||
|
assert.Equal(t, ToString(8), "8")
|
||||||
|
assert.Equal(t, ToString(8.12), "8.12")
|
||||||
|
assert.Equal(t, ToString([]byte("one time")), "one time")
|
||||||
|
assert.Equal(t, ToString(foo), "one more time")
|
||||||
|
assert.Equal(t, ToString(nil), "")
|
||||||
|
}
|
||||||
|
|
||||||
func TestMaps(t *testing.T) {
|
func TestMaps(t *testing.T) {
|
||||||
var taxonomies = map[interface{}]interface{}{"tag": "tags", "group": "groups"}
|
var taxonomies = map[interface{}]interface{}{"tag": "tags", "group": "groups"}
|
||||||
assert.Equal(t, ToStringMap(taxonomies), map[string]interface{}{"tag": "tags", "group": "groups"})
|
assert.Equal(t, ToStringMap(taxonomies), map[string]interface{}{"tag": "tags", "group": "groups"})
|
||||||
|
151
caste.go
151
caste.go
@ -53,6 +53,84 @@ func ToBoolE(i interface{}) (bool, bool) {
|
|||||||
return false, false
|
return false, false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToFloat64E(i interface{}) (float64, bool) {
|
||||||
|
switch s := i.(type) {
|
||||||
|
case float64:
|
||||||
|
return s, true
|
||||||
|
case float32:
|
||||||
|
return float64(s), true
|
||||||
|
case string:
|
||||||
|
v, err := strconv.ParseFloat(s, 64)
|
||||||
|
if err == nil {
|
||||||
|
return float64(v), true
|
||||||
|
} else {
|
||||||
|
jww.ERROR.Printf("Unable to Cast %#v to float", i)
|
||||||
|
jww.ERROR.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
jww.ERROR.Printf("Unable to Cast %#v to float", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToIntE(i interface{}) (int, bool) {
|
||||||
|
switch s := i.(type) {
|
||||||
|
case int:
|
||||||
|
return s, true
|
||||||
|
case int64:
|
||||||
|
return int(s), true
|
||||||
|
case int32:
|
||||||
|
return int(s), true
|
||||||
|
case int16:
|
||||||
|
return int(s), true
|
||||||
|
case int8:
|
||||||
|
return int(s), true
|
||||||
|
case string:
|
||||||
|
v, err := strconv.ParseInt(s, 0, 0)
|
||||||
|
if err == nil {
|
||||||
|
return int(v), true
|
||||||
|
} else {
|
||||||
|
jww.ERROR.Printf("Unable to Cast %#v to int", i)
|
||||||
|
jww.ERROR.Println(err)
|
||||||
|
}
|
||||||
|
case float64:
|
||||||
|
return int(s), true
|
||||||
|
case bool:
|
||||||
|
if bool(s) {
|
||||||
|
return 1, true
|
||||||
|
} else {
|
||||||
|
return 0, true
|
||||||
|
}
|
||||||
|
case nil:
|
||||||
|
return 0, true
|
||||||
|
default:
|
||||||
|
jww.ERROR.Printf("Unable to Cast %#v to int", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToStringE(i interface{}) (string, bool) {
|
||||||
|
switch s := i.(type) {
|
||||||
|
case string:
|
||||||
|
return s, true
|
||||||
|
case float64:
|
||||||
|
return strconv.FormatFloat(i.(float64), 'f', -1, 64), true
|
||||||
|
case int:
|
||||||
|
return strconv.FormatInt(int64(i.(int)), 10), true
|
||||||
|
case []byte:
|
||||||
|
return string(s), true
|
||||||
|
case nil:
|
||||||
|
return "", true
|
||||||
|
default:
|
||||||
|
jww.ERROR.Printf("Unable to Cast %#v to string", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
func ToStringMapStringE(i interface{}) (map[string]string, bool) {
|
func ToStringMapStringE(i interface{}) (map[string]string, bool) {
|
||||||
var m = map[string]string{}
|
var m = map[string]string{}
|
||||||
|
|
||||||
@ -98,79 +176,6 @@ func ToStringSliceE(i interface{}) ([]string, bool) {
|
|||||||
return a, true
|
return a, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToFloat64E(i interface{}) (float64, bool) {
|
|
||||||
switch s := i.(type) {
|
|
||||||
case float64:
|
|
||||||
return s, true
|
|
||||||
case float32:
|
|
||||||
return float64(s), true
|
|
||||||
|
|
||||||
case string:
|
|
||||||
v, err := strconv.ParseFloat(s, 64)
|
|
||||||
if err == nil {
|
|
||||||
return float64(v), true
|
|
||||||
} else {
|
|
||||||
jww.ERROR.Printf("Unable to Cast %#v to float", i)
|
|
||||||
jww.ERROR.Println(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
jww.ERROR.Printf("Unable to Cast %#v to float", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0.0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToIntE(i interface{}) (int, bool) {
|
|
||||||
switch s := i.(type) {
|
|
||||||
case int:
|
|
||||||
return s, true
|
|
||||||
case int64:
|
|
||||||
return int(s), true
|
|
||||||
case int32:
|
|
||||||
return int(s), true
|
|
||||||
case int16:
|
|
||||||
return int(s), true
|
|
||||||
case int8:
|
|
||||||
return int(s), true
|
|
||||||
case string:
|
|
||||||
v, err := strconv.ParseInt(s, 0, 0)
|
|
||||||
if err == nil {
|
|
||||||
return int(v), true
|
|
||||||
} else {
|
|
||||||
jww.ERROR.Printf("Unable to Cast %#v to int", i)
|
|
||||||
jww.ERROR.Println(err)
|
|
||||||
}
|
|
||||||
case bool:
|
|
||||||
if bool(s) {
|
|
||||||
return 1, true
|
|
||||||
} else {
|
|
||||||
return 0, true
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
jww.ERROR.Printf("Unable to Cast %#v to int", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func ToStringE(i interface{}) (string, bool) {
|
|
||||||
switch s := i.(type) {
|
|
||||||
case string:
|
|
||||||
return s, true
|
|
||||||
case float64:
|
|
||||||
return strconv.FormatFloat(i.(float64), 'f', -1, 64), true
|
|
||||||
case int:
|
|
||||||
return strconv.FormatInt(int64(i.(int)), 10), true
|
|
||||||
case nil:
|
|
||||||
return "", true
|
|
||||||
default:
|
|
||||||
jww.ERROR.Printf("Unable to Cast %#v to string", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", false
|
|
||||||
}
|
|
||||||
|
|
||||||
func StringToDate(s string) (time.Time, error) {
|
func StringToDate(s string) (time.Time, error) {
|
||||||
return parseDateWith(s, []string{
|
return parseDateWith(s, []string{
|
||||||
time.RFC3339,
|
time.RFC3339,
|
||||||
|
Loading…
Reference in New Issue
Block a user