You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

862 lines
14 KiB

package field
import (
"encoding/json"
"fmt"
"math"
"strconv"
"time"
)
type Value struct {
vtype Type
numeric uint64
stringly string
value interface{}
}
func (v Value) MarshalJSON() ([]byte, error) {
b, err := json.Marshal(v.AsInterface())
if err != nil {
return nil, fmt.Errorf("marshal err: %w", err)
}
return b, nil
}
//nolint: gocyclo,gomnd,cyclop
func (v Value) String() string {
switch {
case v.vtype.IsArray(), v.vtype.IsAny():
return fmt.Sprintf("%+v", v.AsInterface())
case v.vtype.IsNil():
return "<nil>"
case v.vtype.IsString():
return v.asString()
case v.vtype.IsBool():
return strconv.FormatBool(v.asBool())
case v.vtype.IsInt(), v.vtype.IsInt8(), v.vtype.IsInt16(), v.vtype.IsInt32():
return strconv.Itoa(v.asInt())
case v.vtype.IsInt64():
return strconv.FormatInt(v.asInt64(), 10)
case v.vtype.IsUint(), v.vtype.IsUint8(), v.vtype.IsUint16(), v.vtype.IsUint32(), v.vtype.IsUint64():
return strconv.FormatUint(v.asUint64(), 10)
case v.vtype.IsFloat64():
return strconv.FormatFloat(v.asFloat64(), 'g', -1, 64)
case v.vtype.IsFloat32():
return strconv.FormatFloat(float64(v.asFloat32()), 'g', -1, 32)
case v.vtype.IsComplex128():
return strconv.FormatComplex(v.asComplex128(), 'g', -1, 128)
case v.vtype.IsComplex64():
return strconv.FormatComplex(complex128(v.asComplex64()), 'g', -1, 64)
case v.vtype.IsBinary():
return string(v.asBinary())
case v.vtype.IsDuration():
return v.asDuration().String()
case v.vtype.IsTime():
return v.asTime().Format(v.asString())
case v.vtype.IsError():
return v.asError().Error()
}
return fmt.Sprintf("%+v", v.AsInterface())
}
//nolint: gocyclo,cyclop
func (v Value) AsInterface() interface{} {
switch {
case v.vtype.IsArray():
return v.value
case v.vtype.IsNil():
return nil
case v.vtype.IsString():
return v.asString()
case v.vtype.IsBool():
return v.asBool()
case v.vtype.IsInt():
return v.asInt()
case v.vtype.IsInt8():
return v.asInt8()
case v.vtype.IsInt16():
return v.asInt16()
case v.vtype.IsInt32():
return v.asInt32()
case v.vtype.IsInt64():
return v.asInt64()
case v.vtype.IsUint():
return v.asUint()
case v.vtype.IsUint8():
return v.asUint8()
case v.vtype.IsUint16():
return v.asUint16()
case v.vtype.IsUint32():
return v.asUint32()
case v.vtype.IsUint64():
return v.asUint64()
case v.vtype.IsFloat32():
return v.asFloat32()
case v.vtype.IsFloat64():
return v.asFloat64()
case v.vtype.IsComplex64():
return v.asComplex64()
case v.vtype.IsComplex128():
return v.asComplex128()
case v.vtype.IsUintptr():
return v.asUintptr()
case v.vtype.IsBinary():
return v.asBinary()
case v.vtype.IsDuration():
return v.asDuration()
case v.vtype.IsTime():
return v.asTime()
case v.vtype.IsError():
return v.asError()
}
return v.value
}
func (v Value) IsArray() bool {
return v.vtype.IsArray()
}
func (v Value) IsNil() bool {
return v.vtype.IsNil()
}
func (v Value) IsString() bool {
return v.vtype.IsString()
}
func (v Value) IsBool() bool {
return v.vtype.IsBool()
}
func (v Value) IsInt() bool {
return v.vtype.IsInt()
}
func (v Value) IsInt8() bool {
return v.vtype.IsInt8()
}
func (v Value) IsInt16() bool {
return v.vtype.IsInt16()
}
func (v Value) IsInt32() bool {
return v.vtype.IsInt32()
}
func (v Value) IsInt64() bool {
return v.vtype.IsInt64()
}
func (v Value) IsUint() bool {
return v.vtype.IsUint()
}
func (v Value) IsUint8() bool {
return v.vtype.IsUint8()
}
func (v Value) IsUint16() bool {
return v.vtype.IsUint16()
}
func (v Value) IsUint32() bool {
return v.vtype.IsUint32()
}
func (v Value) IsUint64() bool {
return v.vtype.IsUint64()
}
func (v Value) IsFloat32() bool {
return v.vtype.IsFloat32()
}
func (v Value) IsFloat64() bool {
return v.vtype.IsFloat64()
}
func (v Value) IsComplex64() bool {
return v.vtype.IsComplex64()
}
func (v Value) IsComplex128() bool {
return v.vtype.IsComplex128()
}
func (v Value) IsUintptr() bool {
return v.vtype.IsUintptr()
}
func (v Value) IsBinary() bool {
return v.vtype.IsBinary()
}
func (v Value) IsDuration() bool {
return v.vtype.IsDuration()
}
func (v Value) IsTime() bool {
return v.vtype.IsTime()
}
func (v Value) IsError() bool {
return v.vtype.IsError()
}
func (v Value) asString() string {
return v.stringly
}
func (v Value) asBool() bool {
return v.numeric == 1
}
func (v Value) asInt() int {
return int(v.numeric)
}
func (v Value) asInt8() int8 {
return int8(v.numeric)
}
func (v Value) asInt16() int16 {
return int16(v.numeric)
}
func (v Value) asInt32() int32 {
return int32(v.numeric)
}
func (v Value) asInt64() int64 {
return int64(v.numeric)
}
func (v Value) asUint() uint {
return uint(v.numeric)
}
func (v Value) asUint8() uint8 {
return uint8(v.numeric)
}
func (v Value) asUint16() uint16 {
return uint16(v.numeric)
}
func (v Value) asUint32() uint32 {
return uint32(v.numeric)
}
func (v Value) asUint64() uint64 {
return v.numeric
}
func (v Value) asFloat32() float32 {
return math.Float32frombits(uint32(v.numeric))
}
func (v Value) asFloat64() float64 {
return math.Float64frombits(v.numeric)
}
func (v Value) asComplex64() complex64 {
cmplex, _ := v.value.(complex64)
return cmplex
}
func (v Value) asComplex128() complex128 {
cmplex, _ := v.value.(complex128)
return cmplex
}
func (v Value) asUintptr() uintptr {
val, _ := v.value.(uintptr)
return val
}
func (v Value) asBinary() []byte {
bytes, _ := v.value.([]byte)
return bytes
}
func (v Value) asDuration() time.Duration {
duration, _ := v.value.(time.Duration)
return duration
}
func (v Value) asTime() time.Time {
value, _ := v.value.(time.Time)
return value
}
func (v Value) asError() error {
err, _ := v.value.(error)
return err
}
func nilValue(t Type) Value {
return Value{
vtype: t | TypeNil,
value: nil,
numeric: 0,
stringly: "",
}
}
func stringValue(v string) Value {
return Value{
stringly: v,
vtype: TypeString,
numeric: 0,
value: nil,
}
}
func stringsValue(v []string) Value {
return Value{
value: v,
vtype: TypeString | TypeArray,
numeric: 0,
stringly: "",
}
}
func stringpValue(v *string) Value {
if v != nil {
return stringValue(*v)
}
return nilValue(TypeString)
}
func boolValue(b bool) Value {
if b {
return Value{
numeric: 1,
vtype: TypeBool,
value: nil,
stringly: "",
}
}
return Value{
vtype: TypeBool,
value: nil,
numeric: 0,
stringly: "",
}
}
func boolsValue(b []bool) Value {
return Value{
value: b,
vtype: TypeBool | TypeArray,
numeric: 0,
stringly: "",
}
}
func boolpValue(b *bool) Value {
if b != nil {
return boolValue(*b)
}
return nilValue(TypeBool)
}
func intValue(i int) Value {
return Value{
vtype: TypeInt,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func intsValue(i []int) Value {
return Value{
value: i,
vtype: TypeInt | TypeArray,
numeric: 0,
stringly: "",
}
}
func intpValue(in *int) Value {
if in != nil {
return intValue(*in)
}
return nilValue(TypeInt)
}
func int8Value(i int8) Value {
return Value{
vtype: TypeInt8,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func int8sValue(i []int8) Value {
return Value{
value: i,
vtype: TypeInt8 | TypeArray,
numeric: 0,
stringly: "",
}
}
func int8pValue(in *int8) Value {
if in != nil {
return int8Value(*in)
}
return nilValue(TypeInt8)
}
func int16Value(i int16) Value {
return Value{
vtype: TypeInt16,
numeric: uint64(i),
value: 0,
stringly: "",
}
}
func int16sValue(i []int16) Value {
return Value{
value: i,
vtype: TypeInt16 | TypeArray,
numeric: 0,
stringly: "",
}
}
func int16pValue(in *int16) Value {
if in != nil {
return int16Value(*in)
}
return nilValue(TypeInt16)
}
func int32Value(i int32) Value {
return Value{
vtype: TypeInt32,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func int32sValue(i []int32) Value {
return Value{
value: i,
vtype: TypeInt32 | TypeArray,
numeric: 0,
stringly: "",
}
}
func int32pValue(in *int32) Value {
if in != nil {
return int32Value(*in)
}
return nilValue(TypeInt32)
}
func int64Value(i int64) Value {
return Value{
vtype: TypeInt64,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func int64sValue(i []int64) Value {
return Value{
value: i,
vtype: TypeInt64 | TypeArray,
numeric: 0,
stringly: "",
}
}
func int64pValue(in *int64) Value {
if in != nil {
return int64Value(*in)
}
return nilValue(TypeInt64)
}
func uintValue(i uint) Value {
return Value{
vtype: TypeUint,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func uintsValue(i []uint) Value {
return Value{
value: i,
vtype: TypeUint | TypeArray,
numeric: 0,
stringly: "",
}
}
func uintpValue(in *uint) Value {
if in != nil {
return uintValue(*in)
}
return nilValue(TypeUint)
}
func uint8Value(i uint8) Value {
return Value{
vtype: TypeUint8,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func uint8sValue(i []uint8) Value {
return Value{
value: i,
vtype: TypeUint8 | TypeArray,
numeric: 0,
stringly: "",
}
}
func uint8pValue(in *uint8) Value {
if in != nil {
return uint8Value(*in)
}
return nilValue(TypeUint8)
}
func uint16Value(i uint16) Value {
return Value{
vtype: TypeUint16,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func uint16sValue(i []uint16) Value {
return Value{
value: i,
vtype: TypeUint16 | TypeArray,
numeric: 0,
stringly: "",
}
}
func uint16pValue(in *uint16) Value {
if in != nil {
return uint16Value(*in)
}
return nilValue(TypeUint16)
}
func uint32Value(i uint32) Value {
return Value{
vtype: TypeUint32,
numeric: uint64(i),
value: nil,
stringly: "",
}
}
func uint32sValue(i []uint32) Value {
return Value{
value: i,
vtype: TypeUint32 | TypeArray,
numeric: 0,
stringly: "",
}
}
func uint32pValue(in *uint32) Value {
if in != nil {
return uint32Value(*in)
}
return nilValue(TypeUint32)
}
func uint64Value(i uint64) Value {
return Value{
vtype: TypeUint64,
numeric: i,
value: nil,
stringly: "",
}
}
func uint64sValue(i []uint64) Value {
return Value{
value: i,
vtype: TypeUint64 | TypeArray,
numeric: 0,
stringly: "",
}
}
func uint64pValue(in *uint64) Value {
if in != nil {
return uint64Value(*in)
}
return nilValue(TypeUint64)
}
func float32Value(i float32) Value {
return Value{
vtype: TypeFloat32,
numeric: uint64(math.Float32bits(i)),
value: nil,
stringly: "",
}
}
func float32sValue(i []float32) Value {
return Value{
value: i,
vtype: TypeFloat32 | TypeArray,
numeric: 0,
stringly: "",
}
}
func float32pValue(in *float32) Value {
if in != nil {
return float32Value(*in)
}
return nilValue(TypeFloat32)
}
func float64Value(i float64) Value {
return Value{
vtype: TypeFloat64,
numeric: math.Float64bits(i),
value: nil,
stringly: "",
}
}
func float64sValue(i []float64) Value {
return Value{
value: i,
vtype: TypeFloat64 | TypeArray,
numeric: 0,
stringly: "",
}
}
func float64pValue(in *float64) Value {
if in != nil {
return float64Value(*in)
}
return nilValue(TypeFloat64)
}
func complex64Value(in complex64) Value {
return Value{
vtype: TypeComplex64,
value: in,
numeric: 0,
stringly: "",
}
}
func complex64sValue(in []complex64) Value {
return Value{
vtype: TypeComplex64 | TypeArray,
value: in,
numeric: 0,
stringly: "",
}
}
func complex64pValue(in *complex64) Value {
if in != nil {
return complex64Value(*in)
}
return nilValue(TypeComplex64)
}
func complex128Value(in complex128) Value {
return Value{
vtype: TypeComplex64,
value: in,
numeric: 0,
stringly: "",
}
}
func complex128sValue(in []complex128) Value {
return Value{
vtype: TypeComplex128 | TypeArray,
value: in,
numeric: 0,
stringly: "",
}
}
func complex128pValue(in *complex128) Value {
if in != nil {
return complex128Value(*in)
}
return nilValue(TypeComplex128)
}
func uintptrValue(in uintptr) Value {
return Value{
vtype: TypeUintptr,
numeric: 0,
stringly: "",
value: in,
}
}
func uintptrsValue(in []uintptr) Value {
return Value{
vtype: TypeUintptr | TypeArray,
value: in,
numeric: 0,
stringly: "",
}
}
func uintptrpValue(in *uintptr) Value {
if in != nil {
return uintptrValue(*in)
}
return nilValue(TypeUintptr)
}
func bytesValue(in []byte) Value {
return Value{
vtype: TypeBinary,
value: in,
numeric: 0,
stringly: "",
}
}
func durationValue(in time.Duration) Value {
return Value{
vtype: TypeDuration,
value: in,
numeric: 0,
stringly: "",
}
}
func durationsValue(in []time.Duration) Value {
return Value{
vtype: TypeDuration | TypeArray,
value: in,
numeric: 0,
stringly: "",
}
}
func durationpValue(in *time.Duration) Value {
if in != nil {
return durationValue(*in)
}
return nilValue(TypeDuration)
}
func timeValue(in time.Time) Value {
return formatTimeValue(time.RFC3339, in)
}
func timesValue(in []time.Time) Value {
return formatTimesValue(time.RFC3339, in)
}
func timepValue(in *time.Time) Value {
return formatTimepValue(time.RFC3339, in)
}
func formatTimeValue(format string, in time.Time) Value {
return Value{
vtype: TypeTime,
value: in,
stringly: format,
numeric: 0,
}
}
func formatTimesValue(format string, in []time.Time) Value {
return Value{
vtype: TypeTime | TypeArray,
value: in,
stringly: format,
numeric: 0,
}
}
func formatTimepValue(format string, in *time.Time) Value {
if in != nil {
return formatTimeValue(format, *in)
}
return nilValue(TypeTime)
}
func errorValue(in error) Value {
if in != nil {
return Value{
vtype: TypeError,
value: in,
numeric: 0,
stringly: "",
}
}
return nilValue(TypeError)
}
func errorsValue(in []error) Value {
return Value{
vtype: TypeError | TypeArray,
value: in,
numeric: 0,
stringly: "",
}
}