| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 | package iiimport (	"fmt"	"reflect"	"golib/v4/features/mo")var (	errTypeReturn = func(f *FieldInfo, v any) error {		return fmt.Errorf("%s: %s's value type muse be %s, got: %s", getCallerName(), f.Name, f.Type.String(), valueType(v))	}	errRequired = func(name string, v any) error {		return fmt.Errorf("%s: %s's value are Required, got value: %v", getCallerName(), name, v)	}	errValidate = func(err error, f *FieldInfo) error {		return fmt.Errorf("%s: Validate failed: %s: %s(%s)", getCallerName(), err, f.Label, f.Name)	}	errMinReturn = func(f *FieldInfo, min float64) error {		return fmt.Errorf("%s: %f < Minimum(%f)", getCallerName(), min, f.Minimum)	}	errMaxReturn = func(f *FieldInfo, max float64) error {		return fmt.Errorf("%s: %f > Maximum(%f)", getCallerName(), max, f.Maximum)	}	errEnumReturn = func(f *FieldInfo, v any) error {		return fmt.Errorf("%s: %v not in Enums group", getCallerName(), v)	})// Validate 用于校验传入的 value 是否符合该字段的数据类型.// 注意: 即使 Required == false 当调用 Validate 时也会验证数据是否合法, 否则你应该在上层代码中移除该字段func (f *FieldInfo) Validate(value any) error {	if value == nil {		return errRequired(f.Name, value)	}	switch f.Type {	case mo.TypeDouble:		return f.validateDouble(value)	case mo.TypeString:		return f.validateString(value)	case mo.TypeObject:		return f.validateObject(value)	case mo.TypeArray:		return f.validateArray(value)	case mo.TypeBinary:		return f.validateBinary(value)	case mo.TypeObjectId:		return f.validateObjectID(value)	case mo.TypeBoolean:		return f.validateBoolean(value)	case mo.TypeDateTime:		return f.validateDateTime(value)	case mo.TypeInt32:		return f.validateInt32(value)	case mo.TypeInt64:		return f.validateInt64(value)	default:		return fmt.Errorf("unsupported type: %s", valueType(f.Type))	}}func (f *FieldInfo) validateDouble(value any) error {	v, ok := value.(float64)	if !ok {		return errTypeReturn(f, value)	}	if f.Minimum != 0 && v < f.Minimum {		return errMinReturn(f, v)	}	if f.Maximum != 0 && v > f.Maximum {		return errMaxReturn(f, v)	}	if !f.inEnums(v) {		return errEnumReturn(f, v)	}	return nil}func (f *FieldInfo) validateString(value any) error {	v, ok := value.(string)	if !ok {		return errTypeReturn(f, value)	}	length := float64(len(v))	if f.Minimum != 0 && length < f.Minimum {		return errMinReturn(f, length)	}	if f.Maximum != 0 && length > f.Maximum {		return errMaxReturn(f, length)	}	if !f.inEnums(v) {		return errEnumReturn(f, v)	}	if f.pattern != nil {		if !f.pattern.MatchString(v) {			return fmt.Errorf("validateString: Pattern not matched(%s)", v)		}	}	return nil}// validateObject// 2023/01/28: from eric: object/map 类型的数据不允许 value 再次作为 map, 即只能存在一层 mapfunc (f *FieldInfo) validateObject(value any) error {	if value == nil {		return errNil	}	rv := reflect.ValueOf(value)	if rv.Type().Kind() != reflect.Slice && rv.Type().Kind() != reflect.Array {		return errTypeReturn(f, value)	}	if f.NoField {		return nil	}	rvLen := rv.Len()	length := float64(rvLen)	if f.Minimum != 0 && length < f.Minimum {		return errMinReturn(f, length)	}	if f.Maximum != 0 && length > f.Maximum {		return errMaxReturn(f, length)	}	for i := 0; i < rvLen; i++ {		ele, ok := rv.Index(i).Interface().(mo.E)		if !ok {			return errTypeReturn(f, value)		}		sub, found := f.SubField(ele.Key)		if !found {			return fmt.Errorf("validateObject: not found key: %s", sub.Name)		}		if err := sub.Validate(ele.Value); err != nil {			return err		}	}	return nil}// validateArray 校验数组// 如果 Items == "array" 时则仅判断长度// 如果 Items == "object" 除判断长度之外会进一步判断 map 中是否包含 Fields.Namefunc (f *FieldInfo) validateArray(value any) error {	if value == nil {		return errNil	}	rv := reflect.ValueOf(value)	if rv.Type().Kind() != reflect.Slice && rv.Type().Kind() != reflect.Array {		return errTypeReturn(f, value)	}	length := float64(rv.Len())	if f.Minimum != 0 && length < f.Minimum {		return errMinReturn(f, length)	}	if f.Maximum != 0 && length > f.Maximum {		return errMaxReturn(f, length)	}	switch f.Items {	case FieldItemsArray, "":		for i := 0; i < int(length); i++ {			eleType := rv.Index(i).Kind()			if eleType == reflect.Array || eleType == reflect.Slice {				return fmt.Errorf("validateArray: the %d element type can not be %s", i, eleType.String())			}			if eleType == reflect.Map {				if err := f.validateObject(rv.Index(i).Interface()); err != nil {					return fmt.Errorf("validateArray: %s", err)				}			}		}	case FieldItemsObject:		for i := 0; i < int(length); i++ {			if err := f.validateObject(rv.Index(i).Interface()); err != nil {				return fmt.Errorf("validateArray: %s", err)			}		}	case FieldItemsObjectId:		for i := 0; i < int(length); i++ {			eleType := rv.Index(i)			if oid, ok := eleType.Interface().(mo.ObjectID); ok && !oid.IsZero() {				continue			}			return fmt.Errorf("validateArray: the %d element type can not be %s", i, eleType.Kind())		}	default:		return fmt.Errorf("validateArray: unknown items: %s", f.Items)	}	return nil}func (f *FieldInfo) validateBinary(value any) error {	var length float64	switch v := value.(type) {	case []byte:		length = float64(len(v))	case mo.Binary:		length = float64(len(v.Data))	default:		return errTypeReturn(f, value)	}	if f.Minimum != 0 && length < f.Minimum {		return errMinReturn(f, length)	}	if f.Maximum != 0 && length > f.Maximum {		return errMaxReturn(f, length)	}	if !f.inEnums(value) {		return errEnumReturn(f, value)	}	return nil}func (f *FieldInfo) validateObjectID(value any) error {	val, ok := value.(mo.ObjectID)	if !ok {		return errTypeReturn(f, value)	}	if f.Name == mo.OID {		if val.IsZero() {			return errTypeReturn(f, val)		}	}	if !f.inEnums(value) {		return errEnumReturn(f, value)	}	return nil}func (f *FieldInfo) validateBoolean(value any) error {	_, ok := value.(bool)	if !ok {		return errTypeReturn(f, value)	}	if !f.inEnums(value) {		return errEnumReturn(f, value)	}	return nil}func (f *FieldInfo) validateDateTime(value any) error {	val, ok := value.(mo.DateTime)	if !ok {		return errTypeReturn(f, value)	}	if val.Time().IsZero() {		return errTypeReturn(f, value)	}	if !f.inEnums(value) {		return errEnumReturn(f, value)	}	return nil}func (f *FieldInfo) validateInt32(value any) error {	v, ok := value.(int32)	if !ok {		return errTypeReturn(f, value)	}	if f.Minimum != 0 && float64(v) < f.Minimum {		return errMinReturn(f, float64(v))	}	if f.Maximum != 0 && float64(v) > f.Maximum {		return errMaxReturn(f, float64(v))	}	if !f.inEnums(value) {		return errEnumReturn(f, value)	}	return nil}func (f *FieldInfo) validateInt64(value any) error {	v, ok := value.(int64)	if !ok {		return errTypeReturn(f, value)	}	if f.Minimum != 0 && float64(v) < f.Minimum {		return errMinReturn(f, float64(v))	}	if f.Maximum != 0 && float64(v) > f.Maximum {		return errMaxReturn(f, float64(v))	}	if !f.inEnums(value) {		return errEnumReturn(f, value)	}	return nil}func (f *FieldInfo) inEnums(v any) bool {	if len(f.Enums) == 0 {		return true	}	for i := 0; i < len(f.Enums); i++ {		if f.enums[i] == v {			return true		}	}	return false}
 |