package bind import ( "reflect" "time" ) func bindScalar(receiver reflect.Value, values []any) bool { if !receiver.IsValid() || len(values) == 0 { return false } if !acceptsScalar(receiver.Type()) { return false } if len(values) == 1 { receiver = unpackValue(receiver, pointer|iface|slice) if !receiver.CanSet() { return false } v := reflect.ValueOf(values[0]) v = unpackValue(v, pointer|iface) if !v.IsValid() && !isAny(receiver.Type()) { return false } if !v.IsValid() { receiver.Set(reflect.Zero(receiver.Type())) return true } vv, ok := scan(receiver.Type(), v.Interface()) if !ok { return false } receiver.Set(reflect.ValueOf(vv)) 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 hasCircularType(t) { return reflect.Zero(t), false } for _, vi := range values { if hasCircularReference(reflect.ValueOf(vi)) { 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 { v := reflect.ValueOf(receiver) if hasCircularReference(v) { return false } for _, vi := range values { if hasCircularReference(reflect.ValueOf(vi)) { return false } } return bindScalar(v, values) } func bindScalarCreateReflect[T any](values []any) (T, bool) { t := reflect.TypeFor[T]() v, ok := bindScalarCreate(t, values) if !ok { var tt T return tt, false } 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) }