2025-08-27 21:03:25 +02:00
|
|
|
package bind
|
|
|
|
|
|
|
|
|
|
import "reflect"
|
|
|
|
|
|
|
|
|
|
func bindScalar(receiver reflect.Value, values []any) bool {
|
|
|
|
|
if len(values) == 0 {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !acceptsScalar(receiver.Type()) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(values) == 1 {
|
|
|
|
|
receiver = unpackValue(receiver, pointer|iface|slice)
|
|
|
|
|
r := reflect.ValueOf(values[0])
|
|
|
|
|
r = unpackValue(r, pointer|iface|slice)
|
|
|
|
|
v, ok := scan(receiver.Type(), r.Interface())
|
|
|
|
|
if !ok {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !receiver.CanSet() {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
receiver.Set(reflect.ValueOf(v))
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
receiver = unpackValue(receiver, pointer|iface|anytype)
|
|
|
|
|
if receiver.Kind() != reflect.Slice || receiver.Len() < len(values) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i := range values {
|
|
|
|
|
if !bindScalar(receiver.Index(i), []any{values[i]}) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func bindScalarCreate(t reflect.Type, values []any) (reflect.Value, bool) {
|
|
|
|
|
if len(values) == 0 {
|
|
|
|
|
return reflect.Zero(t), false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !acceptsScalar(t) {
|
|
|
|
|
return reflect.Zero(t), false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
receiver, ok := allocate(t, len(values))
|
|
|
|
|
if !ok {
|
|
|
|
|
return reflect.Zero(t), false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !bindScalar(receiver, values) {
|
|
|
|
|
return reflect.Zero(t), false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return receiver, true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func bindScalarReflect(receiver any, values []any) bool {
|
2025-08-28 05:04:06 +02:00
|
|
|
v := reflect.ValueOf(receiver)
|
2025-08-31 00:40:47 +02:00
|
|
|
if hasCircularReference(v) {
|
2025-08-28 05:04:06 +02:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, vi := range values {
|
2025-08-31 00:40:47 +02:00
|
|
|
if hasCircularReference(reflect.ValueOf(vi)) {
|
2025-08-28 05:04:06 +02:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bindScalar(v, values)
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func bindScalarCreateReflect[T any](values []any) (T, bool) {
|
2025-08-28 05:04:06 +02:00
|
|
|
t := reflect.TypeFor[T]()
|
2025-08-31 00:40:47 +02:00
|
|
|
if hasCircularType(t) {
|
2025-08-28 05:04:06 +02:00
|
|
|
var tt T
|
|
|
|
|
return tt, false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, vi := range values {
|
2025-08-31 00:40:47 +02:00
|
|
|
if hasCircularReference(reflect.ValueOf(vi)) {
|
2025-08-28 05:04:06 +02:00
|
|
|
var tt T
|
|
|
|
|
return tt, false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v, ok := bindScalarCreate(t, values)
|
2025-08-27 21:03:25 +02:00
|
|
|
if !ok {
|
2025-08-28 05:04:06 +02:00
|
|
|
var tt T
|
|
|
|
|
return tt, false
|
2025-08-27 21:03:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return v.Interface().(T), true
|
|
|
|
|
}
|