package pgtype

import (
	
)

func ( any) error {
	 := reflect.ValueOf()

	// AssignTo dst must always be a pointer
	if .Kind() != reflect.Ptr {
		return &nullAssignmentError{dst: }
	}

	 := .Elem()

	switch .Kind() {
	case reflect.Ptr, reflect.Slice, reflect.Map:
		.Set(reflect.Zero(.Type()))
		return nil
	}

	return &nullAssignmentError{dst: }
}

var kindTypes map[reflect.Kind]reflect.Type

func ( reflect.Value,  reflect.Type) (any, bool) {
	 := .Convert()
	return .Interface(), .Type() != .Type()
}

// GetAssignToDstType attempts to convert dst to something AssignTo can assign
// to. If dst is a pointer to pointer it allocates a value and returns the
// dereferences pointer. If dst is a named type such as *Foo where Foo is type
// Foo int16, it converts dst to *int16.
//
// GetAssignToDstType returns the converted dst and a bool representing if any
// change was made.
func ( any) (any, bool) {
	 := reflect.ValueOf()

	// AssignTo dst must always be a pointer
	if .Kind() != reflect.Ptr {
		return nil, false
	}

	 := .Elem()

	// if dst is a pointer to pointer, allocate space try again with the dereferenced pointer
	if .Kind() == reflect.Ptr {
		.Set(reflect.New(.Type().Elem()))
		return .Interface(), true
	}

	// if dst is pointer to a base type that has been renamed
	if ,  := kindTypes[.Kind()];  {
		return toInterface(, reflect.PtrTo())
	}

	if .Kind() == reflect.Slice {
		if ,  := kindTypes[.Type().Elem().Kind()];  {
			return toInterface(, reflect.PtrTo(reflect.SliceOf()))
		}
	}

	if .Kind() == reflect.Array {
		if ,  := kindTypes[.Type().Elem().Kind()];  {
			return toInterface(, reflect.PtrTo(reflect.ArrayOf(.Len(), )))
		}
	}

	if .Kind() == reflect.Struct {
		if .Type().NumField() == 1 && .Type().Field(0).Anonymous {
			 = .Field(0).Addr()
			 := .Type().Field(0).Type
			if .Kind() == reflect.Array {
				if ,  := kindTypes[.Elem().Kind()];  {
					return toInterface(, reflect.PtrTo(reflect.ArrayOf(.Len(), )))
				}
			}
			if ,  := kindTypes[.Kind()];  && .CanInterface() {
				return .Interface(), true
			}
		}
	}

	return nil, false
}

func () {
	kindTypes = map[reflect.Kind]reflect.Type{
		reflect.Bool:    reflect.TypeFor[bool](),
		reflect.Float32: reflect.TypeFor[float32](),
		reflect.Float64: reflect.TypeFor[float64](),
		reflect.Int:     reflect.TypeFor[int](),
		reflect.Int8:    reflect.TypeFor[int8](),
		reflect.Int16:   reflect.TypeFor[int16](),
		reflect.Int32:   reflect.TypeFor[int32](),
		reflect.Int64:   reflect.TypeFor[int64](),
		reflect.Uint:    reflect.TypeFor[uint](),
		reflect.Uint8:   reflect.TypeFor[uint8](),
		reflect.Uint16:  reflect.TypeFor[uint16](),
		reflect.Uint32:  reflect.TypeFor[uint32](),
		reflect.Uint64:  reflect.TypeFor[uint64](),
		reflect.String:  reflect.TypeFor[string](),
	}
}