mirror of https://github.com/spf13/cast.git
Add function to convert to byte array
This commit is contained in:
parent
ba0a5b63c8
commit
acb6966dc1
11
cast.go
11
cast.go
|
@ -6,7 +6,10 @@
|
||||||
// Package cast provides easy and safe casting in Go.
|
// Package cast provides easy and safe casting in Go.
|
||||||
package cast
|
package cast
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// ToBool casts an interface to a bool type.
|
// ToBool casts an interface to a bool type.
|
||||||
func ToBool(i interface{}) bool {
|
func ToBool(i interface{}) bool {
|
||||||
|
@ -169,6 +172,12 @@ func ToIntSlice(i interface{}) []int {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToBytes casts an interface to a []byte type.
|
||||||
|
func ToBytes(i interface{}, b binary.ByteOrder) []byte {
|
||||||
|
v, _ := ToBytesE(i, b)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
// ToDurationSlice casts an interface to a []time.Duration type.
|
// ToDurationSlice casts an interface to a []time.Duration type.
|
||||||
func ToDurationSlice(i interface{}) []time.Duration {
|
func ToDurationSlice(i interface{}) []time.Duration {
|
||||||
v, _ := ToDurationSliceE(i)
|
v, _ := ToDurationSliceE(i)
|
||||||
|
|
89
cast_test.go
89
cast_test.go
|
@ -6,10 +6,12 @@
|
||||||
package cast
|
package cast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"math"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -289,6 +291,93 @@ func TestToStringE(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestToBytesE(t *testing.T) {
|
||||||
|
c := qt.New(t)
|
||||||
|
|
||||||
|
//Overkill?
|
||||||
|
expected8 := []byte{math.MaxInt8}
|
||||||
|
expectedLittle16 := append([]byte{math.MaxUint8}, math.MaxInt8)
|
||||||
|
expectedBig16 := append(expected8, math.MaxUint8)
|
||||||
|
expectedLittle32 := append([]byte{math.MaxUint8, math.MaxUint8}, expectedLittle16...)
|
||||||
|
expectedBig32 := append(expectedBig16, math.MaxUint8, math.MaxUint8)
|
||||||
|
expectedLittle64 := append([]byte{math.MaxUint8, math.MaxUint8, math.MaxUint8, math.MaxUint8}, expectedLittle32...)
|
||||||
|
expectedBig64 := append(expectedBig32, math.MaxUint8, math.MaxUint8, math.MaxUint8, math.MaxUint8)
|
||||||
|
|
||||||
|
expectedU8 := []byte{math.MaxUint8}
|
||||||
|
expectedLittleU16 := append(expectedU8, expectedU8...)
|
||||||
|
expectedLittleU32 := append(expectedLittleU16, expectedLittleU16...)
|
||||||
|
expectedLittleU64 := append(expectedLittleU32, expectedLittleU32...)
|
||||||
|
expectedBigU16 := append(expected8, expectedU8...)
|
||||||
|
expectedBigU32 := append(expectedBigU16, expectedLittleU16...)
|
||||||
|
expectedBigU64 := append(expectedBigU32, expectedLittleU32...)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
input interface{}
|
||||||
|
byteOrder binary.ByteOrder
|
||||||
|
expect []byte
|
||||||
|
iserr bool
|
||||||
|
}{
|
||||||
|
//LittleEndian
|
||||||
|
{byte(math.MaxUint8), binary.LittleEndian, expectedU8, false},
|
||||||
|
{math.MaxInt32, binary.LittleEndian, expectedLittle32, false},
|
||||||
|
{math.MaxInt64, binary.LittleEndian, expectedLittle64, false},
|
||||||
|
{uint(math.MaxUint32), binary.LittleEndian, expectedLittleU32, false},
|
||||||
|
{uint(math.MaxUint64), binary.LittleEndian, expectedLittleU64, false},
|
||||||
|
{int8(math.MaxInt8), binary.LittleEndian, expected8, false},
|
||||||
|
{int16(math.MaxInt16), binary.LittleEndian, expectedLittle16, false},
|
||||||
|
{int32(math.MaxInt32), binary.LittleEndian, expectedLittle32, false},
|
||||||
|
{int64(math.MaxInt64), binary.LittleEndian, expectedLittle64, false},
|
||||||
|
{uint8(math.MaxUint8), binary.LittleEndian, expectedU8, false},
|
||||||
|
{uint16(math.MaxUint16), binary.LittleEndian, expectedLittleU16, false},
|
||||||
|
{uint32(math.MaxUint32), binary.LittleEndian, expectedLittleU32, false},
|
||||||
|
{uint64(math.MaxUint64), binary.LittleEndian, expectedLittleU64, false},
|
||||||
|
{[]byte("one time"), binary.LittleEndian, []byte("one time"), false},
|
||||||
|
{"one more time", binary.LittleEndian, []byte("one more time"), false},
|
||||||
|
//BigEndian
|
||||||
|
{byte(math.MaxUint8), binary.BigEndian, expectedU8, false},
|
||||||
|
{math.MaxInt32, binary.BigEndian, expectedBig32, false},
|
||||||
|
{math.MaxInt64, binary.BigEndian, expectedBig64, false},
|
||||||
|
{uint(math.MaxInt32), binary.BigEndian, expectedBigU32, false},
|
||||||
|
{uint(math.MaxInt64), binary.BigEndian, expectedBigU64, false},
|
||||||
|
{int8(math.MaxInt8), binary.BigEndian, expected8, false},
|
||||||
|
{int16(math.MaxInt16), binary.BigEndian, expectedBig16, false},
|
||||||
|
{int32(math.MaxInt32), binary.BigEndian, expectedBig32, false},
|
||||||
|
{int64(math.MaxInt64), binary.BigEndian, expectedBig64, false},
|
||||||
|
{uint8(math.MaxUint8), binary.BigEndian, expectedU8, false},
|
||||||
|
{uint16(math.MaxInt16), binary.BigEndian, expectedBigU16, false},
|
||||||
|
{uint32(math.MaxInt32), binary.BigEndian, expectedBigU32, false},
|
||||||
|
{uint64(math.MaxInt64), binary.BigEndian, expectedBigU64, false},
|
||||||
|
{[]byte("one time"), binary.BigEndian, []byte("one time"), false},
|
||||||
|
{"one more time", binary.BigEndian, []byte("one more time"), false},
|
||||||
|
// errors
|
||||||
|
{testing.T{}, binary.LittleEndian, []byte{}, true},
|
||||||
|
{int8(-8), binary.LittleEndian, []byte{}, true},
|
||||||
|
{int16(-136), binary.LittleEndian, []byte{}, true},
|
||||||
|
{int32(-2184), binary.LittleEndian, []byte{}, true},
|
||||||
|
{int64(-34952), binary.LittleEndian, []byte{}, true},
|
||||||
|
{true, binary.LittleEndian, []byte{}, true},
|
||||||
|
{false, binary.LittleEndian, []byte{}, true},
|
||||||
|
{nil, binary.LittleEndian, []byte{}, true},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, test := range tests {
|
||||||
|
errmsg := qt.Commentf("i = %d", i) // assert helper message
|
||||||
|
|
||||||
|
v, err := ToBytesE(test.input, test.byteOrder)
|
||||||
|
if test.iserr {
|
||||||
|
c.Assert(err, qt.IsNotNil, errmsg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Assert(err, qt.IsNil, errmsg)
|
||||||
|
c.Assert(v, qt.DeepEquals, test.expect, errmsg)
|
||||||
|
|
||||||
|
// Non-E test
|
||||||
|
v = ToBytes(test.input, test.byteOrder)
|
||||||
|
c.Assert(v, qt.DeepEquals, test.expect, errmsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type foo struct {
|
type foo struct {
|
||||||
val string
|
val string
|
||||||
}
|
}
|
||||||
|
|
88
caste.go
88
caste.go
|
@ -6,10 +6,12 @@
|
||||||
package cast
|
package cast
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -1340,6 +1342,92 @@ func ToIntSliceE(i interface{}) ([]int, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ToBytesE(i interface{}, b binary.ByteOrder) ([]byte, error) {
|
||||||
|
i = indirect(i)
|
||||||
|
|
||||||
|
if i == nil {
|
||||||
|
return []byte{}, fmt.Errorf("unable to cast %#v of type %T to []byte", i, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := i.(type) {
|
||||||
|
case []byte:
|
||||||
|
return v, nil
|
||||||
|
case byte:
|
||||||
|
return []byte{v}, nil
|
||||||
|
case int8:
|
||||||
|
if v < 0 {
|
||||||
|
return []byte{}, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
return []byte{byte(v)}, nil
|
||||||
|
case int16:
|
||||||
|
if v < 0 {
|
||||||
|
return []byte{}, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
a := make([]byte, 2)
|
||||||
|
b.PutUint16(a, uint16(v))
|
||||||
|
return a, nil
|
||||||
|
case int32:
|
||||||
|
if v < 0 {
|
||||||
|
return []byte{}, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
a := make([]byte, 4)
|
||||||
|
b.PutUint32(a, uint32(v))
|
||||||
|
return a, nil
|
||||||
|
case int64:
|
||||||
|
if v < 0 {
|
||||||
|
return []byte{}, errNegativeNotAllowed
|
||||||
|
}
|
||||||
|
a := make([]byte, 8)
|
||||||
|
b.PutUint64(a, uint64(v))
|
||||||
|
return a, nil
|
||||||
|
case uint16:
|
||||||
|
a := make([]byte, 2)
|
||||||
|
b.PutUint16(a, v)
|
||||||
|
return a, nil
|
||||||
|
case uint32:
|
||||||
|
a := make([]byte, 4)
|
||||||
|
b.PutUint32(a, v)
|
||||||
|
return a, nil
|
||||||
|
case uint64:
|
||||||
|
a := make([]byte, 8)
|
||||||
|
b.PutUint64(a, v)
|
||||||
|
return a, nil
|
||||||
|
case int:
|
||||||
|
switch true {
|
||||||
|
case v < 0:
|
||||||
|
return []byte{}, errNegativeNotAllowed
|
||||||
|
case v <= math.MaxUint32:
|
||||||
|
a := make([]byte, 4)
|
||||||
|
b.PutUint32(a, uint32(v))
|
||||||
|
return a, nil
|
||||||
|
default:
|
||||||
|
a := make([]byte, 8)
|
||||||
|
b.PutUint64(a, uint64(v))
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
case uint:
|
||||||
|
switch true {
|
||||||
|
case v < 0:
|
||||||
|
return []byte{}, errNegativeNotAllowed
|
||||||
|
case v <= math.MaxUint32:
|
||||||
|
a := make([]byte, 4)
|
||||||
|
b.PutUint32(a, uint32(v))
|
||||||
|
return a, nil
|
||||||
|
case v <= math.MaxUint64:
|
||||||
|
a := make([]byte, 8)
|
||||||
|
b.PutUint64(a, uint64(v))
|
||||||
|
return a, nil
|
||||||
|
default:
|
||||||
|
return []byte{}, fmt.Errorf("unable to cast %#v of type %T to []byte", i, i)
|
||||||
|
}
|
||||||
|
case string:
|
||||||
|
return []byte(v), nil
|
||||||
|
default:
|
||||||
|
return []byte{}, fmt.Errorf("unable to cast %#v of type %T to []byte", i, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// ToDurationSliceE casts an interface to a []time.Duration type.
|
// ToDurationSliceE casts an interface to a []time.Duration type.
|
||||||
func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
|
func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
|
||||||
if i == nil {
|
if i == nil {
|
||||||
|
|
Loading…
Reference in New Issue