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
|
||||
}
|
||||
|
||||
func bindFieldsReflect(structure any, values []Field) []Field {
|
||||
receiver := reflect.ValueOf(structure)
|
||||
if hasCircularReference(receiver) {
|
||||
return values
|
||||
}
|
||||
|
||||
if !acceptsFields(receiver.Type()) {
|
||||
return values
|
||||
}
|
||||
|
||||
func bindFields(receiver reflect.Value, values []Field) []Field {
|
||||
unmatched, try := filterFields(fieldHasCircRef, values)
|
||||
groups := groupFields(try)
|
||||
for _, g := range groups {
|
||||
@ -465,3 +456,42 @@ func bindFieldsReflect(structure any, values []Field) []Field {
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user