package schema

import (
	
	
)

var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem()

type isZeroer interface {
	IsZero() bool
}

type IsZeroerFunc func(reflect.Value) bool

func ( reflect.Type) IsZeroerFunc {
	if .Implements(isZeroerType) {
		return isZeroInterface
	}

	 := .Kind()

	if  != reflect.Ptr {
		 := reflect.PtrTo()
		if .Implements(isZeroerType) {
			return addrChecker(isZeroInterface)
		}
	}

	switch  {
	case reflect.Array:
		if .Elem().Kind() == reflect.Uint8 {
			return isZeroBytes
		}
		return isZeroLen
	case reflect.String:
		return isZeroLen
	case reflect.Bool:
		return isZeroBool
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return isZeroInt
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return isZeroUint
	case reflect.Float32, reflect.Float64:
		return isZeroFloat
	case reflect.Interface, reflect.Ptr, reflect.Slice, reflect.Map:
		return isNil
	}

	if .Implements(driverValuerType) {
		return isZeroDriverValue
	}

	return notZero
}

func ( IsZeroerFunc) IsZeroerFunc {
	return func( reflect.Value) bool {
		if !.CanAddr() {
			return false
		}
		return (.Addr())
	}
}

func ( reflect.Value) bool {
	if .Kind() == reflect.Ptr && .IsNil() {
		return true
	}
	return .Interface().(isZeroer).IsZero()
}

func ( reflect.Value) bool {
	if .Kind() == reflect.Ptr {
		return .IsNil()
	}

	 := .Interface().(driver.Valuer)
	,  := .Value()
	if  != nil {
		return false
	}
	return  == nil
}

func ( reflect.Value) bool {
	return .Len() == 0
}

func ( reflect.Value) bool {
	return .IsNil()
}

func ( reflect.Value) bool {
	return !.Bool()
}

func ( reflect.Value) bool {
	return .Int() == 0
}

func ( reflect.Value) bool {
	return .Uint() == 0
}

func ( reflect.Value) bool {
	return .Float() == 0
}

func ( reflect.Value) bool {
	 := .Slice(0, .Len()).Bytes()
	for ,  := range  {
		if  != 0 {
			return false
		}
	}
	return true
}

func ( reflect.Value) bool {
	return false
}