add bind scalar from field type
This commit is contained in:
parent
8683d8ba40
commit
f3e17035cd
13
lib.go
13
lib.go
@ -18,12 +18,10 @@ const (
|
||||
Uint16 FieldType = reflect.Uint16
|
||||
Uint32 FieldType = reflect.Uint32
|
||||
Uint64 FieldType = reflect.Uint64
|
||||
Uintptr FieldType = reflect.Uintptr
|
||||
Float32 FieldType = reflect.Float32
|
||||
Float64 FieldType = reflect.Float64
|
||||
String FieldType = reflect.String
|
||||
Any FieldType = reflect.Interface
|
||||
Struct FieldType = reflect.Struct
|
||||
Duration FieldType = 0xfffe
|
||||
Time FieldType = 0xffff
|
||||
)
|
||||
@ -48,16 +46,21 @@ func BindScalar(receiver any, value ...any) bool {
|
||||
return bindScalarReflect(receiver, value)
|
||||
}
|
||||
|
||||
// BindScalarCreate is like BindScalar, but it allocates the receiver from the type T.
|
||||
// CreateAndBindScalar is like BindScalar, but it allocates the receiver from the type T.
|
||||
func CreateAndBindScalar[T any](value ...any) (T, bool) {
|
||||
return bindScalarCreateReflect[T](value)
|
||||
}
|
||||
|
||||
// BindScalarCreate is like BindScalar, but it allocates the receiver from the type t.
|
||||
// CreateAndBindScalarFor is like BindScalar, but it allocates the receiver from the type t.
|
||||
func CreateAndBindScalarFor(t reflect.Type, value ...any) (reflect.Value, bool) {
|
||||
return bindScalarCreate(t, value)
|
||||
}
|
||||
|
||||
// CreateAndBindScalarFieldType is like BindScalar, but it allocates the receiver from the field type t.
|
||||
func CreateAndBindScalarFieldType(t FieldType, value ...any) (reflect.Value, bool) {
|
||||
return bindScalarCreateFieldType(t, value)
|
||||
}
|
||||
|
||||
// ValueByPath defines a field for input to BindFields or BindFieldsCreate. It defines the field by its exact
|
||||
// field path in the receiver structure.
|
||||
func ValueByPath(path []string, value any) Field {
|
||||
@ -145,7 +148,7 @@ func CreateAndBindFor(t reflect.Type, value ...Field) (reflect.Value, []Field) {
|
||||
return bindFieldsCreate(t, value)
|
||||
}
|
||||
|
||||
// AcceptsScalar checks if a type can be used with BindScalarCreate or the values of the type with BindScalar.
|
||||
// AcceptsScalar checks if a type can be used with CreateScalarAndBind or the values of the type with BindScalar.
|
||||
func AcceptsScalar[T any]() bool {
|
||||
return acceptsScalarReflect[T]()
|
||||
}
|
||||
|
||||
49
scalar.go
49
scalar.go
@ -1,6 +1,9 @@
|
||||
package bind
|
||||
|
||||
import "reflect"
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func bindScalar(receiver reflect.Value, values []any) bool {
|
||||
if !receiver.IsValid() || len(values) == 0 {
|
||||
@ -107,3 +110,47 @@ func bindScalarCreateReflect[T any](values []any) (T, bool) {
|
||||
|
||||
return v.Interface().(T), true
|
||||
}
|
||||
|
||||
func bindScalarCreateFieldType(t FieldType, values []any) (reflect.Value, bool) {
|
||||
var r reflect.Type
|
||||
switch t {
|
||||
case Bool:
|
||||
r = reflect.TypeFor[bool]()
|
||||
case Int:
|
||||
r = reflect.TypeFor[int]()
|
||||
case Int8:
|
||||
r = reflect.TypeFor[int8]()
|
||||
case Int16:
|
||||
r = reflect.TypeFor[int16]()
|
||||
case Int32:
|
||||
r = reflect.TypeFor[int32]()
|
||||
case Int64:
|
||||
r = reflect.TypeFor[int64]()
|
||||
case Uint:
|
||||
r = reflect.TypeFor[uint]()
|
||||
case Uint8:
|
||||
r = reflect.TypeFor[uint8]()
|
||||
case Uint16:
|
||||
r = reflect.TypeFor[uint16]()
|
||||
case Uint32:
|
||||
r = reflect.TypeFor[uint32]()
|
||||
case Uint64:
|
||||
r = reflect.TypeFor[uint64]()
|
||||
case Float32:
|
||||
r = reflect.TypeFor[float32]()
|
||||
case Float64:
|
||||
r = reflect.TypeFor[float64]()
|
||||
case String:
|
||||
r = reflect.TypeFor[string]()
|
||||
case Any:
|
||||
r = reflect.TypeFor[any]()
|
||||
case Duration:
|
||||
r = reflect.TypeFor[time.Duration]()
|
||||
case Time:
|
||||
r = reflect.TypeFor[time.Time]()
|
||||
default:
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
|
||||
return bindScalarCreate(r, values)
|
||||
}
|
||||
|
||||
117
scalar_test.go
117
scalar_test.go
@ -5,6 +5,7 @@ import (
|
||||
"reflect"
|
||||
"slices"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type valuer interface {
|
||||
@ -258,4 +259,120 @@ func TestScalar(t *testing.T) {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("bind from field type", func(t *testing.T) {
|
||||
t.Run("bool", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Bool, true); !ok || !v.Interface().(bool) {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("int", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Int, 42); !ok || v.Interface().(int) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("int8", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Int8, 42); !ok || v.Interface().(int8) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("int16", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Int16, 42); !ok || v.Interface().(int16) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("int32", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Int32, 42); !ok || v.Interface().(int32) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("int64", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Int64, 42); !ok || v.Interface().(int64) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("uint", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Uint, 42); !ok || v.Interface().(uint) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("uint8", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Uint8, 42); !ok || v.Interface().(uint8) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("uint16", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Uint16, 42); !ok || v.Interface().(uint16) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("uint32", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Uint32, 42); !ok || v.Interface().(uint32) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("uint64", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Uint64, 42); !ok || v.Interface().(uint64) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("float32", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Float32, 42); !ok || v.Interface().(float32) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("float64", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Float64, 42); !ok || v.Interface().(float64) != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("string", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.String, "foo"); !ok || v.Interface().(string) != "foo" {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("any", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Any, 42); !ok || v.Interface() != 42 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("duration", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Duration, time.Second); !ok || v.Interface().(time.Duration) != time.Second {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("time", func(t *testing.T) {
|
||||
if v, ok := bind.CreateAndBindScalarFieldType(bind.Time, "14:22:45"); !ok || v.Interface().(time.Time).Hour() != 14 {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("fail", func(t *testing.T) {
|
||||
if _, ok := bind.CreateAndBindScalarFieldType(bind.Int, "foo"); ok {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("unsupported type", func(t *testing.T) {
|
||||
if _, ok := bind.CreateAndBindScalarFieldType(bind.Duration*bind.Time, "foo"); ok {
|
||||
t.Fatal()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user