improve parameter parsing feature for ghttp.Request

This commit is contained in:
John
2020-01-01 14:57:57 +08:00
parent 9219471f67
commit 604a10400d
5 changed files with 17 additions and 17 deletions

View File

@ -12,7 +12,9 @@ import (
"github.com/fatih/structs"
)
// MapField retrieves struct field as map[name/tag]*Field from <pointer>, and returns it.
// MapField retrieves struct field as map[name/tag]*Field from <pointer>, and returns the map.
//
// The parameter <priority> specifies the priority tag array for retrieving from high to low.
//
// The parameter <recursive> specifies whether retrieving the struct field recursively.
//

View File

@ -22,7 +22,7 @@ func Test_Params_Json_Request(t *testing.T) {
Id int
Name string
Time *time.Time
Pass1 string `p:"password1" v:"password1"`
Pass1 string `p:"password1"`
Pass2 string `p:"password2" v:"required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致"`
}
p := ports.PopRand()

View File

@ -62,14 +62,8 @@ regex 格式regex:pattern 说明:参
// 自定义错误信息: map[键名] => 字符串|map[规则]错误信息
type CustomMsg = map[string]interface{}
// 解析单条sequence tag格式: [数值键名/别名@]校验规则[#错误提示]
// 其中校验规则如果有多个那么以"|"符号分隔,错误提示同理。
// 解析单条sequence tag格式: [alias@]rule[...#msg...]
func parseSequenceTag(tag string) (name, rule, msg string) {
// Just a alias name.
// Eg: password1
if gregex.IsMatchString(`^\w+$`, tag) {
return tag, "", ""
}
// Complete sequence tag.
// Eg: required|length:2,20|password3|same:password1#||密码强度不足|两次密码不一致
match, _ := gregex.MatchString(`\s*((\w+)\s*@){0,1}\s*([^#]+)\s*(#\s*(.*)){0,1}\s*`, tag)

View File

@ -14,18 +14,18 @@ import (
)
var (
// 同时支持gvalid、valid和v标签优先使用gvalid
structTagPriority = []string{"gvalid", "valid", "v"}
structTagPriority = []string{"gvalid", "valid", "v"} // structTagPriority specifies the validation tag priority array.
aliasNameTagPriority = []string{"param", "params", "p"} // aliasNameTagPriority specifies the alias tag priority array.
)
// 校验struct对象属性object参数也可以是一个指向对象的指针返回值同CheckMap方法。
// struct的数据校验结果信息是顺序的。
func CheckStruct(object interface{}, rules interface{}, msgs ...CustomMsg) *Error {
// 字段别名记录用于msgs覆盖struct tag的
fieldAliases := make(map[string]string)
params := make(map[string]interface{})
checkRules := make(map[string]string)
customMsgs := make(CustomMsg)
// 字段别名记录用于msgs覆盖struct tag的
fieldAliases := make(map[string]string)
// 返回的顺序规则
errorRules := make([]string, 0)
// 返回的校验错误
@ -62,14 +62,19 @@ func CheckStruct(object interface{}, rules interface{}, msgs ...CustomMsg) *Erro
errorRules = append(errorRules, name+"@"+rule)
}
// 不支持校验错误顺序: map[键名]校验规则
// Map type rules does not support sequence.
// Format: map[key]rule
case map[string]string:
checkRules = v
}
// Checks and extends the parameters map with struct alias tag.
for nameOrTag, field := range structs.MapField(object, aliasNameTagPriority, true) {
params[nameOrTag] = field.Value()
params[field.Name()] = field.Value()
}
// 首先, 按照属性循环一遍将struct的属性、数值、tag解析
for nameOrTag, field := range structs.MapField(object, structTagPriority, true) {
fieldName := field.Name()
params[fieldName] = field.Value()
// MapField返回map[name/tag]*Field当nameOrTag != fieldName时nameOrTag为tag
if nameOrTag != fieldName {
// sequence tag == struct tag, 这里的name为别名

View File

@ -15,7 +15,6 @@ import (
)
func Test_Check(t *testing.T) {
gtest.Case(t, func() {
rule := "abc:6,16"
val1 := 0
@ -238,7 +237,7 @@ func Test_Phone(t *testing.T) {
err2 := gvalid.Check("13619908979", "phone", nil)
err3 := gvalid.Check("16719908979", "phone", nil)
err4 := gvalid.Check("19719908989", "phone", nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err1.String(), nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)