create receiver and bind fields
This commit is contained in:
parent
0a5ab05c88
commit
5363818043
50
field.go
50
field.go
@ -445,16 +445,7 @@ func groupFields(f []Field) [][]Field {
|
|||||||
return groups
|
return groups
|
||||||
}
|
}
|
||||||
|
|
||||||
func bindFieldsReflect(structure any, values []Field) []Field {
|
func bindFields(receiver reflect.Value, values []Field) []Field {
|
||||||
receiver := reflect.ValueOf(structure)
|
|
||||||
if hasCircularReference(receiver) {
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
if !acceptsFields(receiver.Type()) {
|
|
||||||
return values
|
|
||||||
}
|
|
||||||
|
|
||||||
unmatched, try := filterFields(fieldHasCircRef, values)
|
unmatched, try := filterFields(fieldHasCircRef, values)
|
||||||
groups := groupFields(try)
|
groups := groupFields(try)
|
||||||
for _, g := range groups {
|
for _, g := range groups {
|
||||||
@ -465,3 +456,42 @@ func bindFieldsReflect(structure any, values []Field) []Field {
|
|||||||
|
|
||||||
return unmatched
|
return unmatched
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func bindFieldsReflect(structure any, values []Field) []Field {
|
||||||
|
receiver := reflect.ValueOf(structure)
|
||||||
|
if hasCircularReference(receiver) {
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
if !acceptsFields(receiver.Type()) {
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
return bindFields(receiver, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bindFieldsCreateReflect[T any](values []Field) (T, []Field) {
|
||||||
|
t := reflect.TypeFor[T]()
|
||||||
|
if hasCircularType(t) {
|
||||||
|
var r T
|
||||||
|
return r, values
|
||||||
|
}
|
||||||
|
|
||||||
|
if !acceptsFields(t) {
|
||||||
|
var r T
|
||||||
|
return r, values
|
||||||
|
}
|
||||||
|
|
||||||
|
receiver, ok := allocate(t, 1)
|
||||||
|
if !ok {
|
||||||
|
var r T
|
||||||
|
return r, values
|
||||||
|
}
|
||||||
|
|
||||||
|
unmatched := bindFields(receiver, values)
|
||||||
|
if len(unmatched) == len(values) {
|
||||||
|
receiver = reflect.Zero(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return receiver.Interface().(T), unmatched
|
||||||
|
}
|
||||||
|
|||||||
@ -701,4 +701,40 @@ func TestField(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("bind fields create", func(t *testing.T) {
|
||||||
|
t.Run("circular type", func(t *testing.T) {
|
||||||
|
type s struct {
|
||||||
|
Foo int
|
||||||
|
Bar *s
|
||||||
|
}
|
||||||
|
_, u := bind.BindFieldsCreate[s](bind.NamedValue("foo", 42))
|
||||||
|
if len(u) != 1 {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("type does not accept fields", func(t *testing.T) {
|
||||||
|
_, u := bind.BindFieldsCreate[[]int](bind.NamedValue("foo", 42))
|
||||||
|
if len(u) != 1 {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("zero value when no fields were bound", func(t *testing.T) {
|
||||||
|
type s struct{ Foo int }
|
||||||
|
v, u := bind.BindFieldsCreate[*s](bind.NamedValue("bar", 42))
|
||||||
|
if len(u) != 1 || v != nil {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("create receiver", func(t *testing.T) {
|
||||||
|
type s struct{ Foo int }
|
||||||
|
v, u := bind.BindFieldsCreate[*s](bind.NamedValue("foo", 42))
|
||||||
|
if len(u) != 0 || v == nil || v.Foo != 42 {
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
3
lib.go
3
lib.go
@ -65,8 +65,7 @@ func BindFields(structure any, values ...Field) []Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BindFieldsCreate[T any](values ...Field) (T, []Field) {
|
func BindFieldsCreate[T any](values ...Field) (T, []Field) {
|
||||||
var t T
|
return bindFieldsCreateReflect[T](values)
|
||||||
return t, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AcceptsScalar[T any]() bool {
|
func AcceptsScalar[T any]() bool {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user