github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zvalid/bind.go (about)

     1  package zvalid
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/sohaha/zlsgo/zreflect"
    11  )
    12  
    13  // ValidEle ValidEle
    14  type ValidEle struct {
    15  	target interface{}
    16  	source Engine
    17  }
    18  
    19  // Silent an error occurred during filtering, no error is returned
    20  func (v Engine) Silent() Engine {
    21  	v.silent = true
    22  	return v
    23  }
    24  
    25  // Default if a filtering error occurs, the default value is assigned to the variable
    26  func (v Engine) Default(value interface{}) Engine {
    27  	return pushQueue(&v, func(v *Engine) *Engine {
    28  		if v.value == "" {
    29  			v.err = setError(v, "未设置验证值")
    30  		}
    31  		v.defaultValue = value
    32  		return v
    33  	}, true)
    34  }
    35  
    36  // Separator specify the separator of the slice type
    37  func (v Engine) Separator(sep string) Engine {
    38  	if v.err != nil || v.value == "" {
    39  		return v
    40  	}
    41  	v.sep = sep
    42  	return v
    43  }
    44  
    45  // BatchError  multiple error
    46  func BatchError(rules ...Engine) error {
    47  	for i := range rules {
    48  		err := rules[i].Error()
    49  		if err != nil {
    50  			return err
    51  		}
    52  	}
    53  	return nil
    54  }
    55  
    56  // Batch assign multiple filtered results to the specified object
    57  func Batch(elements ...*ValidEle) error {
    58  	for k := range elements {
    59  		e := elements[k]
    60  		if e == nil {
    61  			return nil
    62  		}
    63  		err := Var(e.target, e.source)
    64  		if err != nil {
    65  			return err
    66  		}
    67  	}
    68  	return nil
    69  }
    70  
    71  // BatchVar assign the filtered result to the specified variable
    72  func BatchVar(target interface{}, source Engine) *ValidEle {
    73  	return &ValidEle{
    74  		target: target,
    75  		source: source,
    76  	}
    77  }
    78  
    79  // Var assign the filtered result to the specified variable
    80  func Var(target interface{}, source Engine, name ...string) error {
    81  	source = *source.valid()
    82  	if len(name) > 0 {
    83  		source.name = name[0]
    84  	}
    85  	if source.err != nil && source.defaultValue == nil {
    86  		if source.silent {
    87  			return nil
    88  		}
    89  		return source.err
    90  	}
    91  	var (
    92  		val reflect.Value
    93  		k   reflect.Kind
    94  	)
    95  	val, ok := target.(reflect.Value)
    96  	if !ok {
    97  		val = zreflect.ValueOf(target)
    98  		if val.Kind() != reflect.Ptr {
    99  			if source.silent {
   100  				return nil
   101  			}
   102  			return fmt.Errorf("parameter must pass in a pointer type: %s", source.name)
   103  		}
   104  		if !val.Elem().CanSet() {
   105  			if source.silent {
   106  				return nil
   107  			}
   108  			return fmt.Errorf("target value of the variable cannot be changed: %s", source.name)
   109  		}
   110  		val = val.Elem()
   111  		k = val.Type().Kind()
   112  	} else {
   113  		k = val.Type().Kind()
   114  	}
   115  
   116  	if source.err == nil && source.value != "" {
   117  		source.err = setRawValue(k, val, source.value, source.sep)
   118  	}
   119  
   120  	if source.err != nil && source.defaultValue != nil {
   121  		if err := setDefaultValue(k, val, source.defaultValue); err != nil {
   122  			if source.silent {
   123  				return nil
   124  			}
   125  			return err
   126  		}
   127  		return nil
   128  	} else if source.err != nil {
   129  		if source.silent {
   130  			return nil
   131  		}
   132  		return errors.New(source.name + source.err.Error())
   133  	}
   134  
   135  	return nil
   136  }
   137  
   138  func setRawValue(k reflect.Kind, val reflect.Value, value string, sep string) error {
   139  	typeErr := errors.New("不能用" + k.String() + "类型赋值")
   140  	switch k {
   141  	case reflect.String:
   142  		val.SetString(value)
   143  	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
   144  		v, err := strconv.ParseInt(value, 10, 64)
   145  		if err != nil {
   146  			return errors.New("必须是整数")
   147  		}
   148  		if val.OverflowInt(v) {
   149  			return typeErr
   150  		}
   151  		val.SetInt(v)
   152  	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
   153  		v, err := strconv.ParseUint(value, 10, 64)
   154  		if err != nil {
   155  			return errors.New("必须是无符号整数")
   156  		}
   157  		if val.OverflowUint(v) {
   158  			return typeErr
   159  		}
   160  		val.SetUint(v)
   161  	case reflect.Float32, reflect.Float64:
   162  		v, err := strconv.ParseFloat(value, 64)
   163  		if err != nil {
   164  			return errors.New("必须是小数")
   165  		}
   166  		if val.OverflowFloat(v) {
   167  			return typeErr
   168  		}
   169  		val.SetFloat(v)
   170  	case reflect.Bool:
   171  		v, err := strconv.ParseBool(value)
   172  		if err != nil {
   173  			return errors.New("必须是布尔值")
   174  		}
   175  		val.SetBool(v)
   176  	case reflect.Slice:
   177  		sliceType := val.Type().String()
   178  		if sliceType == "[]string" {
   179  			if sep == "" {
   180  				return errors.New("过滤规则的分隔符参数(sep)未定义")
   181  			}
   182  			val.Set(zreflect.ValueOf(strings.Split(value, sep)))
   183  		}
   184  	default:
   185  		return typeErr
   186  	}
   187  
   188  	return nil
   189  }
   190  
   191  func setDefaultValue(targetTypeOf reflect.Kind, targetValueOf reflect.Value, value interface{}) error {
   192  	valueTypeOf := zreflect.ValueOf(value)
   193  	if valueTypeOf.Kind() != targetTypeOf {
   194  		return errors.New("值类型默认值类型不相同" + valueTypeOf.String() + "/" + targetTypeOf.String())
   195  	}
   196  	targetValueOf.Set(valueTypeOf)
   197  	return nil
   198  }