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
|
Uint16 FieldType = reflect.Uint16
|
||||||
Uint32 FieldType = reflect.Uint32
|
Uint32 FieldType = reflect.Uint32
|
||||||
Uint64 FieldType = reflect.Uint64
|
Uint64 FieldType = reflect.Uint64
|
||||||
Uintptr FieldType = reflect.Uintptr
|
|
||||||
Float32 FieldType = reflect.Float32
|
Float32 FieldType = reflect.Float32
|
||||||
Float64 FieldType = reflect.Float64
|
Float64 FieldType = reflect.Float64
|
||||||
String FieldType = reflect.String
|
String FieldType = reflect.String
|
||||||
Any FieldType = reflect.Interface
|
Any FieldType = reflect.Interface
|
||||||
Struct FieldType = reflect.Struct
|
|
||||||
Duration FieldType = 0xfffe
|
Duration FieldType = 0xfffe
|
||||||
Time FieldType = 0xffff
|
Time FieldType = 0xffff
|
||||||
)
|
)
|
||||||
@ -48,16 +46,21 @@ func BindScalar(receiver any, value ...any) bool {
|
|||||||
return bindScalarReflect(receiver, value)
|
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) {
|
func CreateAndBindScalar[T any](value ...any) (T, bool) {
|
||||||
return bindScalarCreateReflect[T](value)
|
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) {
|
func CreateAndBindScalarFor(t reflect.Type, value ...any) (reflect.Value, bool) {
|
||||||
return bindScalarCreate(t, value)
|
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
|
// ValueByPath defines a field for input to BindFields or BindFieldsCreate. It defines the field by its exact
|
||||||
// field path in the receiver structure.
|
// field path in the receiver structure.
|
||||||
func ValueByPath(path []string, value any) Field {
|
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)
|
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 {
|
func AcceptsScalar[T any]() bool {
|
||||||
return acceptsScalarReflect[T]()
|
return acceptsScalarReflect[T]()
|
||||||
}
|
}
|
||||||
|
|||||||
49
scalar.go
49
scalar.go
@ -1,6 +1,9 @@
|
|||||||
package bind
|
package bind
|
||||||
|
|
||||||
import "reflect"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
func bindScalar(receiver reflect.Value, values []any) bool {
|
func bindScalar(receiver reflect.Value, values []any) bool {
|
||||||
if !receiver.IsValid() || len(values) == 0 {
|
if !receiver.IsValid() || len(values) == 0 {
|
||||||
@ -107,3 +110,47 @@ func bindScalarCreateReflect[T any](values []any) (T, bool) {
|
|||||||
|
|
||||||
return v.Interface().(T), true
|
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"
|
"reflect"
|
||||||
"slices"
|
"slices"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type valuer interface {
|
type valuer interface {
|
||||||
@ -258,4 +259,120 @@ func TestScalar(t *testing.T) {
|
|||||||
t.Fatal()
|
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