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
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"encoding/binary"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ToBool casts an interface to a bool type.
|
||||
func ToBool(i interface{}) bool {
|
||||
|
@ -169,6 +172,12 @@ func ToIntSlice(i interface{}) []int {
|
|||
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.
|
||||
func ToDurationSlice(i interface{}) []time.Duration {
|
||||
v, _ := ToDurationSliceE(i)
|
||||
|
|
89
cast_test.go
89
cast_test.go
|
@ -6,10 +6,12 @@
|
|||
package cast
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"math"
|
||||
"path"
|
||||
"reflect"
|
||||
"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 {
|
||||
val string
|
||||
}
|
||||
|
|
88
caste.go
88
caste.go
|
@ -6,10 +6,12 @@
|
|||
package cast
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"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.
|
||||
func ToDurationSliceE(i interface{}) ([]time.Duration, error) {
|
||||
if i == nil {
|
||||
|
|
Loading…
Reference in New Issue