github.com/gogf/gf/v2@v2.7.4/util/gvalid/gvalid.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 // Package gvalid implements powerful and useful data/form validation functionality. 8 package gvalid 9 10 import ( 11 "context" 12 "reflect" 13 "regexp" 14 "strings" 15 16 "github.com/gogf/gf/v2/internal/intlog" 17 "github.com/gogf/gf/v2/text/gregex" 18 "github.com/gogf/gf/v2/util/gtag" 19 ) 20 21 // CustomMsg is the custom error message type, 22 // like: map[field] => string|map[rule]string 23 type CustomMsg = map[string]interface{} 24 25 // fieldRule defined the alias name and rule string for specified field. 26 type fieldRule struct { 27 Name string // Alias name for the field. 28 Rule string // Rule string like: "max:6" 29 IsMeta bool // Is this rule is from gmeta.Meta, which marks it as whole struct rule. 30 FieldKind reflect.Kind // Original kind of struct field, which is used for parameter type checks. 31 FieldType reflect.Type // Type of struct field, which is used for parameter type checks. 32 } 33 34 // iNoValidation is an interface that marks current struct not validated by package `gvalid`. 35 type iNoValidation interface { 36 NoValidation() 37 } 38 39 const ( 40 singleRulePattern = `^([\w-]+):{0,1}(.*)` // regular expression pattern for single validation rule. 41 internalRulesErrRuleName = "InvalidRules" // rule name for internal invalid rules validation error. 42 internalParamsErrRuleName = "InvalidParams" // rule name for internal invalid params validation error. 43 internalObjectErrRuleName = "InvalidObject" // rule name for internal invalid object validation error. 44 internalErrorMapKey = "__InternalError__" // error map key for internal errors. 45 internalDefaultRuleName = "__default__" // default rule name for i18n error message format if no i18n message found for specified error rule. 46 ruleMessagePrefixForI18n = "gf.gvalid.rule." // prefix string for each rule configuration in i18n content. 47 noValidationTagName = gtag.NoValidation // no validation tag name for struct attribute. 48 ruleNameRegex = "regex" // the name for rule "regex" 49 ruleNameNotRegex = "not-regex" // the name for rule "not-regex" 50 ruleNameForeach = "foreach" // the name for rule "foreach" 51 ruleNameBail = "bail" // the name for rule "bail" 52 ruleNameCi = "ci" // the name for rule "ci" 53 emptyJsonArrayStr = "[]" // Empty json string for array type. 54 emptyJsonObjectStr = "{}" // Empty json string for object type. 55 requiredRulesPrefix = "required" // requiredRulesPrefix specifies the rule prefix that must be validated even the value is empty (nil or empty). 56 ) 57 58 var ( 59 // defaultErrorMessages is the default error messages. 60 // Note that these messages are synchronized from ./i18n/en/validation.toml . 61 defaultErrorMessages = map[string]string{ 62 internalDefaultRuleName: "The {field} value `{value}` is invalid", 63 } 64 65 // structTagPriority specifies the validation tag priority array. 66 structTagPriority = []string{gtag.Valid, gtag.ValidShort} 67 68 // aliasNameTagPriority specifies the alias tag priority array. 69 aliasNameTagPriority = []string{gtag.Param, gtag.ParamShort} 70 71 // all internal error keys. 72 internalErrKeyMap = map[string]string{ 73 internalRulesErrRuleName: internalRulesErrRuleName, 74 internalParamsErrRuleName: internalParamsErrRuleName, 75 internalObjectErrRuleName: internalObjectErrRuleName, 76 } 77 // regular expression object for single rule 78 // which is compiled just once and of repeatable usage. 79 ruleRegex, _ = regexp.Compile(singleRulePattern) 80 81 // decorativeRuleMap defines all rules that are just marked rules which have neither functional meaning 82 // nor error messages. 83 decorativeRuleMap = map[string]bool{ 84 ruleNameForeach: true, 85 ruleNameBail: true, 86 ruleNameCi: true, 87 } 88 ) 89 90 // ParseTagValue parses one sequence tag to field, rule and error message. 91 // The sequence tag is like: [alias@]rule[...#msg...] 92 func ParseTagValue(tag string) (field, rule, msg string) { 93 // Complete sequence tag. 94 // Example: name@required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致 95 match, _ := gregex.MatchString(`\s*((\w+)\s*@){0,1}\s*([^#]+)\s*(#\s*(.*)){0,1}\s*`, tag) 96 if len(match) > 5 { 97 msg = strings.TrimSpace(match[5]) 98 rule = strings.TrimSpace(match[3]) 99 field = strings.TrimSpace(match[2]) 100 } else { 101 intlog.Errorf(context.TODO(), `invalid validation tag value: %s`, tag) 102 } 103 return 104 } 105 106 // GetTags returns the validation tags. 107 func GetTags() []string { 108 return structTagPriority 109 }