github.com/artisanhe/tools@v1.0.1-0.20210607022958-19a8fef2eb04/validate/validatetpl/template.go (about)

     1  package validatetpl
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  func GenerateRangeValidateFunc(str_type, str_param string, exc_min, exc_max bool) func(v interface{}) (bool, string) {
    11  	switch str_type {
    12  	case "uint8":
    13  		params := strings.Split(str_param, ",")
    14  		if len(params) == 2 {
    15  			min, err := strconv.ParseUint(params[0], 10, 8)
    16  			if err != nil {
    17  				min = 0
    18  			}
    19  			max, err := strconv.ParseUint(params[1], 10, 8)
    20  			if err != nil {
    21  				max = MAX_UINT8
    22  			}
    23  			return NewRangeValidateUint8(uint8(min), uint8(max), exc_min, exc_max)
    24  		}
    25  	case "int8":
    26  		params := strings.Split(str_param, ",")
    27  		if len(params) == 2 {
    28  			min, err := strconv.ParseInt(params[0], 10, 8)
    29  			if err != nil {
    30  				min = 0
    31  			}
    32  			max, err := strconv.ParseInt(params[1], 10, 8)
    33  			if err != nil {
    34  				max = MAX_INT8
    35  			}
    36  			return NewRangeValidateInt8(int8(min), int8(max), exc_min, exc_max)
    37  		}
    38  	case "uint16":
    39  		params := strings.Split(str_param, ",")
    40  		if len(params) == 2 {
    41  			min, err := strconv.ParseUint(params[0], 10, 16)
    42  			if err != nil {
    43  				min = 0
    44  			}
    45  			max, err := strconv.ParseUint(params[1], 10, 16)
    46  			if err != nil {
    47  				max = MAX_UINT16
    48  			}
    49  			return NewRangeValidateUint16(uint16(min), uint16(max), exc_min, exc_max)
    50  		}
    51  	case "int16":
    52  		params := strings.Split(str_param, ",")
    53  		if len(params) == 2 {
    54  			min, err := strconv.ParseInt(params[0], 10, 16)
    55  			if err != nil {
    56  				min = 0
    57  			}
    58  			max, err := strconv.ParseInt(params[1], 10, 16)
    59  			if err != nil {
    60  				max = MAX_INT16
    61  			}
    62  			return NewRangeValidateInt16(int16(min), int16(max), exc_min, exc_max)
    63  		}
    64  	case "uint32":
    65  		params := strings.Split(str_param, ",")
    66  		if len(params) == 2 {
    67  			min, err := strconv.ParseUint(params[0], 10, 32)
    68  			if err != nil {
    69  				min = 0
    70  			}
    71  			max, err := strconv.ParseUint(params[1], 10, 32)
    72  			if err != nil {
    73  				max = MAX_UINT32
    74  			}
    75  			return NewRangeValidateUint32(uint32(min), uint32(max), exc_min, exc_max)
    76  		}
    77  	case "int32":
    78  		params := strings.Split(str_param, ",")
    79  		if len(params) == 2 {
    80  			min, err := strconv.ParseInt(params[0], 10, 32)
    81  			if err != nil {
    82  				min = 0
    83  			}
    84  			max, err := strconv.ParseInt(params[1], 10, 32)
    85  			if err != nil {
    86  				max = MAX_INT32
    87  			}
    88  			return NewRangeValidateInt32(int32(min), int32(max), exc_min, exc_max)
    89  		}
    90  	case "uint64":
    91  		params := strings.Split(str_param, ",")
    92  		if len(params) == 2 {
    93  			min, err := strconv.ParseUint(params[0], 10, 64)
    94  			if err != nil {
    95  				min = 0
    96  			}
    97  			max, err := strconv.ParseUint(params[1], 10, 64)
    98  			if err != nil {
    99  				max = MAX_UINT64
   100  			}
   101  			return NewRangeValidateUint64(uint64(min), uint64(max), exc_min, exc_max)
   102  		}
   103  	case "int64":
   104  		params := strings.Split(str_param, ",")
   105  		if len(params) == 2 {
   106  			min, err := strconv.ParseInt(params[0], 10, 64)
   107  			if err != nil {
   108  				min = 0
   109  			}
   110  			max, err := strconv.ParseInt(params[1], 10, 64)
   111  			if err != nil {
   112  				max = MAX_INT64
   113  			}
   114  			return NewRangeValidateInt64(int64(min), int64(max), exc_min, exc_max)
   115  		}
   116  	case "float32":
   117  		params := strings.Split(str_param, ",")
   118  		if len(params) == 2 {
   119  			min, err := strconv.ParseFloat(params[0], 32)
   120  			if err != nil {
   121  				min = 0
   122  			}
   123  			max, err := strconv.ParseFloat(params[1], 32)
   124  			if err != nil {
   125  				panic(fmt.Sprintf("general range validate func failed[err:%s, tag:%s]", Float32NoDefaultMaxError, str_type))
   126  			}
   127  			return NewRangeValidateFloat32(float32(min), float32(max), exc_min, exc_max)
   128  		}
   129  	case "float64":
   130  		params := strings.Split(str_param, ",")
   131  		if len(params) == 2 {
   132  			min, err := strconv.ParseFloat(params[0], 64)
   133  			if err != nil {
   134  				min = 0
   135  			}
   136  			max, err := strconv.ParseFloat(params[1], 64)
   137  			if err != nil {
   138  				panic(fmt.Sprintf("general range validate func failed[err:%s, tag:%s]", Float64NoDefaultMaxError, str_type))
   139  			}
   140  			return NewRangeValidateFloat64(float64(min), float64(max), exc_min, exc_max)
   141  		}
   142  	case "string":
   143  		params := strings.Split(str_param, ",")
   144  		if len(params) == 2 {
   145  			min, err := strconv.ParseInt(params[0], 10, 0)
   146  			if err != nil {
   147  				min = 0
   148  			}
   149  
   150  			var max int64 = 0
   151  			if params[1] == UNLIMIT {
   152  				max = STRING_UNLIMIT_VALUE
   153  			} else {
   154  				max, err = strconv.ParseInt(params[1], 10, 0)
   155  				if err != nil {
   156  					max = DEFAULT_MAX_STRING_LENGTH
   157  				}
   158  			}
   159  			return NewValidateStringLength(int(min), int(max))
   160  		}
   161  	case "char":
   162  		params := strings.Split(str_param, ",")
   163  		if len(params) == 2 {
   164  			min, err := strconv.ParseInt(params[0], 10, 0)
   165  			if err != nil {
   166  				min = 0
   167  			}
   168  			max, err := strconv.ParseInt(params[1], 10, 0)
   169  			return NewValidateChar(int(min), int(max))
   170  		}
   171  	case "regexp":
   172  		reg, err := regexp.Compile(str_param)
   173  		if err == nil {
   174  			return NewValidateStringRegExp(reg)
   175  		}
   176  	case "numString":
   177  		params := strings.Split(str_param, ",")
   178  		if len(params) == 2 {
   179  			min, err := strconv.ParseInt(params[0], 10, 0)
   180  			if err != nil {
   181  				min = 0
   182  			}
   183  
   184  			var max int64 = 0
   185  			if params[1] == UNLIMIT {
   186  				max = STRING_UNLIMIT_VALUE
   187  			} else {
   188  				max, err = strconv.ParseInt(params[1], 10, 0)
   189  				if err != nil {
   190  					max = DEFAULT_MAX_STRING_LENGTH
   191  				}
   192  			}
   193  			return NewValidateNumStringLength(int(min), int(max))
   194  		}
   195  	default:
   196  		panic(fmt.Sprintf("general range validate func failed[err:%s, type:%s]", InvalidTypeStringError, str_type))
   197  	}
   198  	panic(fmt.Sprintf("general range validate func failed[err:%s, type:%s]", InvalidParamStringError, str_param))
   199  }
   200  
   201  func GenerateEnumValidateFunc(str_type, str_param string) func(v interface{}) (bool, string) {
   202  	switch str_type {
   203  	case "uint8":
   204  		params := strings.Split(str_param, ",")
   205  		enum_values := []uint8{}
   206  		for _, param := range params {
   207  			num, err := strconv.ParseUint(param, 10, 8)
   208  			if err != nil {
   209  				panic(fmt.Sprintf("general uint8 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   210  			}
   211  			enum_values = append(enum_values, uint8(num))
   212  		}
   213  		return NewEnumValidateUint8(enum_values...)
   214  	case "int8":
   215  		params := strings.Split(str_param, ",")
   216  		enum_values := []int8{}
   217  		for _, param := range params {
   218  			num, err := strconv.ParseInt(param, 10, 8)
   219  			if err != nil {
   220  				panic(fmt.Sprintf("general int8 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   221  			}
   222  			enum_values = append(enum_values, int8(num))
   223  		}
   224  		return NewEnumValidateInt8(enum_values...)
   225  	case "uint16":
   226  		params := strings.Split(str_param, ",")
   227  		enum_values := []uint16{}
   228  		for _, param := range params {
   229  			num, err := strconv.ParseUint(param, 10, 16)
   230  			if err != nil {
   231  				panic(fmt.Sprintf("general uint16 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   232  			}
   233  			enum_values = append(enum_values, uint16(num))
   234  		}
   235  		return NewEnumValidateUint16(enum_values...)
   236  	case "int16":
   237  		params := strings.Split(str_param, ",")
   238  		enum_values := []int16{}
   239  		for _, param := range params {
   240  			num, err := strconv.ParseInt(param, 10, 16)
   241  			if err != nil {
   242  				panic(fmt.Sprintf("general int16 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   243  			}
   244  			enum_values = append(enum_values, int16(num))
   245  		}
   246  		return NewEnumValidateInt16(enum_values...)
   247  	case "uint32":
   248  		params := strings.Split(str_param, ",")
   249  		enum_values := []uint32{}
   250  		for _, param := range params {
   251  			num, err := strconv.ParseUint(param, 10, 32)
   252  			if err != nil {
   253  				panic(fmt.Sprintf("general uint32 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   254  			}
   255  			enum_values = append(enum_values, uint32(num))
   256  		}
   257  		return NewEnumValidateUint32(enum_values...)
   258  	case "int32":
   259  		params := strings.Split(str_param, ",")
   260  		enum_values := []int32{}
   261  		for _, param := range params {
   262  			num, err := strconv.ParseInt(param, 10, 32)
   263  			if err != nil {
   264  				panic(fmt.Sprintf("general int32 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   265  			}
   266  			enum_values = append(enum_values, int32(num))
   267  		}
   268  		return NewEnumValidateInt32(enum_values...)
   269  	case "uint64":
   270  		params := strings.Split(str_param, ",")
   271  		enum_values := []uint64{}
   272  		for _, param := range params {
   273  			num, err := strconv.ParseUint(param, 10, 64)
   274  			if err != nil {
   275  				panic(fmt.Sprintf("general uint64 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   276  			}
   277  			enum_values = append(enum_values, uint64(num))
   278  		}
   279  		return NewEnumValidateUint64(enum_values...)
   280  	case "int64":
   281  		params := strings.Split(str_param, ",")
   282  		enum_values := []int64{}
   283  		for _, param := range params {
   284  			num, err := strconv.ParseInt(param, 10, 64)
   285  			if err != nil {
   286  				panic(fmt.Sprintf("general int64 enum validate func failed[err:%s, param:%s]", InvalidParamStringError, str_param))
   287  			}
   288  			enum_values = append(enum_values, int64(num))
   289  		}
   290  		return NewEnumValidateInt64(enum_values...)
   291  	case "string":
   292  		params := strings.Split(str_param, ",")
   293  		return NewEnumValidateString(params...)
   294  	default:
   295  		panic(fmt.Sprintf("general enum validate func failed[err:%s, type:%s]", InvalidTypeStringError, str_type))
   296  	}
   297  }
   298  
   299  func GenerateDecimalValidateFunc(str_type, str_param string) func(v interface{}) (bool, string) {
   300  	switch str_type {
   301  	case "float32":
   302  		params := strings.Split(str_param, ",")
   303  		if len(params) == 2 {
   304  			total_len, err := strconv.ParseUint(params[0], 10, 32)
   305  			if err != nil {
   306  				panic(fmt.Sprintf("general decimal validate func failed[err:%s, tag:%s]", InvalidTotalLenError, str_type))
   307  			}
   308  			decimal_len, err := strconv.ParseUint(params[1], 10, 32)
   309  			if err != nil {
   310  				panic(fmt.Sprintf("general decimal validate func failed[err:%s, tag:%s]", InvalidDecimalLenError, str_type))
   311  			}
   312  			if total_len > MAX_VALID_DIGIT_FLOAT32 {
   313  				panic(fmt.Sprintf("general decimal validate func failed[float32 valid len should not greater than %d]", MAX_VALID_DIGIT_FLOAT32))
   314  			} else if decimal_len > total_len {
   315  				panic(fmt.Sprintf("general decimal validate func failed[decimal len should not greater than total len[total:%d, decimal:%d]]",
   316  					total_len, decimal_len))
   317  			}
   318  			return NewDecimalValidateFloat32(int(total_len), int(decimal_len))
   319  		}
   320  	case "float64":
   321  		params := strings.Split(str_param, ",")
   322  		if len(params) == 2 {
   323  			total_len, err := strconv.ParseUint(params[0], 10, 32)
   324  			if err != nil {
   325  				panic(fmt.Sprintf("general range validate func failed[err:%s, tag:%s]", InvalidTotalLenError, str_type))
   326  			}
   327  			decimal_len, err := strconv.ParseUint(params[1], 10, 32)
   328  			if err != nil {
   329  				panic(fmt.Sprintf("general range validate func failed[err:%s, tag:%s]", InvalidDecimalLenError, str_type))
   330  			}
   331  			if total_len > MAX_VALID_DIGIT_FLOAT64 {
   332  				panic(fmt.Sprintf("general decimal validate func failed[float32 valid len should not greater than %d]", MAX_VALID_DIGIT_FLOAT32))
   333  			} else if decimal_len > total_len {
   334  				panic(fmt.Sprintf("general decimal validate func failed[decimal len should not greater than total len[total:%d, decimal:%d]]",
   335  					total_len, decimal_len))
   336  			}
   337  			return NewDecimalValidateFloat64(int(total_len), int(decimal_len))
   338  		}
   339  	default:
   340  		panic(fmt.Sprintf("general decimal validate func failed[err:%s, type:%s]", InvalidTypeStringError, str_type))
   341  	}
   342  	panic(fmt.Sprintf("general decimal validate func failed[err:%s, type:%s]", InvalidParamStringError, str_param))
   343  }
   344  func GenerateSliceValidateFunc(str_param, item_tag string) func(v interface{}) (bool, string) {
   345  	params := strings.Split(str_param, ",")
   346  	var min, max uint64
   347  	var err error
   348  	if len(params) == 2 {
   349  		min, err = strconv.ParseUint(params[0], 10, 64)
   350  		if err != nil {
   351  			min = 0
   352  		}
   353  		max, err = strconv.ParseUint(params[1], 10, 64)
   354  		if err != nil {
   355  			max = 0
   356  		}
   357  	}
   358  	return NewValidateSlice(min, max, GenerateValidateFuncByTag(item_tag))
   359  }
   360  
   361  func GenerateValidateFuncByTag(tag string) func(v interface{}) (bool, string) {
   362  	if regexp_range_except_float_tag.MatchString(tag) || regexp_reg_tag.MatchString(tag) {
   363  		param_start := strings.IndexAny(tag, "[(")
   364  		param_end := strings.LastIndexAny(tag, "])")
   365  		if param_start == -1 || param_end == -1 {
   366  			panic(fmt.Sprintf("generate range validate func failed[err:%s, tag:%s]", InvalidTagStringError, tag))
   367  		}
   368  
   369  		lb := tag[param_start : param_start+1]
   370  		rb := tag[param_end : param_end+1]
   371  		str_type := tag[1:param_start]
   372  		str_param := tag[param_start+1 : param_end]
   373  
   374  		exc_min := false
   375  		exc_max := false
   376  		if lb == "(" {
   377  			exc_min = true
   378  		}
   379  		if rb == ")" {
   380  			exc_max = true
   381  		}
   382  		return GenerateRangeValidateFunc(str_type, str_param, exc_min, exc_max)
   383  	} else if regexp_enum_tag.MatchString(tag) {
   384  		param_start := strings.IndexAny(tag, "{")
   385  		param_end := strings.LastIndexAny(tag, "}")
   386  		if param_start == -1 || param_end == -1 {
   387  			panic(fmt.Sprintf("generate enum validate func failed[err:%s, tag:%s]", InvalidTagStringError, tag))
   388  		}
   389  		str_type := tag[1:param_start]
   390  		str_param := tag[param_start+1 : param_end]
   391  		return GenerateEnumValidateFunc(str_type, str_param)
   392  	} else if regexp_array_tag.MatchString(tag) {
   393  		tags := strings.SplitN(tag, ":", 2)
   394  		if len(tags) != 2 {
   395  			//panic(fmt.Sprintf("generate slice validate func failed[err:%s, tag:%s]", InvalidTagStringError, tag))
   396  			tags = append(tags, "@")
   397  		}
   398  		array_tag := tags[0]
   399  		item_tag := tags[1]
   400  
   401  		param_start := strings.IndexAny(array_tag, "[")
   402  		param_end := strings.LastIndexAny(array_tag, "]")
   403  		if param_start == -1 || param_end == -1 {
   404  			panic(fmt.Sprintf("generate slice validate func failed[err:%s, tag:%s]", InvalidTagStringError, tag))
   405  		}
   406  		str_param := tag[param_start+1 : param_end]
   407  		return GenerateSliceValidateFunc(str_param, item_tag)
   408  	} else if regexp_range_float_tag.MatchString(tag) {
   409  		valideFuncList := []func(v interface{}) (bool, string){}
   410  		var param_start, param_end int
   411  		var str_type string
   412  		// float位数校验
   413  		if param_start = strings.IndexAny(tag, "<"); param_start != -1 {
   414  			param_end = strings.LastIndexAny(tag, ">")
   415  			if param_end == -1 {
   416  				panic(fmt.Sprintf("generate range validate func failed[err:%s, tag:%s]", InvalidTagStringError, tag))
   417  			}
   418  
   419  			str_type = tag[1:param_start]
   420  			str_param := tag[param_start+1 : param_end]
   421  			decimalValidFunc := GenerateDecimalValidateFunc(str_type, str_param)
   422  			if decimalValidFunc != nil {
   423  				valideFuncList = append(valideFuncList, decimalValidFunc)
   424  			}
   425  		}
   426  
   427  		// float值范围校验
   428  		if param_start = strings.IndexAny(tag, "[("); param_start != -1 {
   429  			param_end = strings.LastIndexAny(tag, "])")
   430  			if param_end == -1 {
   431  				panic(fmt.Sprintf("generate range validate func failed[err:%s, tag:%s]", InvalidTagStringError, tag))
   432  			}
   433  			// type string
   434  			if str_type == "" {
   435  				str_type = tag[1:param_start]
   436  			}
   437  			// param string
   438  			str_param := tag[param_start+1 : param_end]
   439  
   440  			exc_min := false
   441  			exc_max := false
   442  			if lb := tag[param_start : param_start+1]; lb == "(" {
   443  				exc_min = true
   444  			}
   445  			if rb := tag[param_end : param_end+1]; rb == ")" {
   446  				exc_max = true
   447  			}
   448  
   449  			rangeValidFunc := GenerateRangeValidateFunc(str_type, str_param, exc_min, exc_max)
   450  			if rangeValidFunc != nil {
   451  				valideFuncList = append(valideFuncList, rangeValidFunc)
   452  			}
   453  		}
   454  		return func(v interface{}) (bool, string) {
   455  			for _, validateFunc := range valideFuncList {
   456  				if ok, err_msg := validateFunc(v); !ok {
   457  					return false, err_msg
   458  				}
   459  			}
   460  			return true, ""
   461  		}
   462  	}
   463  
   464  	// 非Auto-Generate类型,从presetValidateFuncMap查询
   465  	if validateFunc, ok := GetValidateFunc(tag); ok {
   466  		return validateFunc
   467  	}
   468  	return nil
   469  }