mirror of
https://gitee.com/johng/gf
synced 2026-06-30 11:05:11 +08:00
change Error from struct to interface for package gvalid;error string update for package gdb
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/i18n/gi18n"
|
||||
@ -13,6 +14,6 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(t.Translate(`hello`))
|
||||
fmt.Println(t.Translate(`{#hello}{#world}!`))
|
||||
fmt.Println(t.Translate(context.TODO(), `hello`))
|
||||
fmt.Println(t.Translate(context.TODO(), `{#hello}{#world}!`))
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gogf/gf/i18n/gi18n"
|
||||
@ -13,6 +14,6 @@ func main() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(t.Translate(`hello`))
|
||||
fmt.Println(t.Translate(`{#hello}{#world}!`))
|
||||
fmt.Println(t.Translate(context.TODO(), `hello`))
|
||||
fmt.Println(t.Translate(context.TODO(), `{#hello}{#world}!`))
|
||||
}
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/i18n/gi18n"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -10,6 +12,12 @@ func main() {
|
||||
orderId = 865271654
|
||||
orderAmount = 99.8
|
||||
)
|
||||
fmt.Println(g.I18n().Tfl(`en`, `{#OrderPaid}`, orderId, orderAmount))
|
||||
fmt.Println(g.I18n().Tfl(`zh-CN`, `{#OrderPaid}`, orderId, orderAmount))
|
||||
fmt.Println(g.I18n().Tf(
|
||||
gi18n.WithLanguage(context.TODO(), `en`),
|
||||
`{#OrderPaid}`, orderId, orderAmount,
|
||||
))
|
||||
fmt.Println(g.I18n().Tf(
|
||||
gi18n.WithLanguage(context.TODO(), `zh-CN`),
|
||||
`{#OrderPaid}`, orderId, orderAmount,
|
||||
))
|
||||
}
|
||||
|
||||
@ -2,15 +2,19 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/i18n/gi18n"
|
||||
"github.com/gogf/gf/net/ghttp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g.I18n().SetPath("/Users/john/Workspace/Go/GOPATH/src/github.com/gogf/gf/.example/i18n/gi18n/i18n")
|
||||
s := g.Server()
|
||||
s.BindHandler("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteTplContent(`{#hello}{#world}!`, g.Map{
|
||||
"I18nLanguage": r.Get("lang", "zh-CN"),
|
||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||
group.Middleware(func(r *ghttp.Request) {
|
||||
r.SetCtx(gi18n.WithLanguage(r.Context(), "zh-CN"))
|
||||
r.Middleware.Next()
|
||||
})
|
||||
group.ALL("/", func(r *ghttp.Request) {
|
||||
r.Response.WriteTplContent(`{#hello}{#world}!`)
|
||||
})
|
||||
})
|
||||
s.SetPort(8199)
|
||||
|
||||
64
.example/net/ghttp/client/middleware/client.go
Normal file
64
.example/net/ghttp/client/middleware/client.go
Normal file
@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/container/garray"
|
||||
"github.com/gogf/gf/crypto/gmd5"
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/internal/json"
|
||||
"github.com/gogf/gf/net/ghttp"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"github.com/gogf/gf/util/guid"
|
||||
"github.com/gogf/gf/util/gutil"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
appId = "123"
|
||||
appSecret = "456"
|
||||
)
|
||||
|
||||
// 注入统一的接口签名参数
|
||||
func injectSignature(jsonContent []byte) []byte {
|
||||
var m map[string]interface{}
|
||||
_ = json.Unmarshal(jsonContent, &m)
|
||||
if len(m) > 0 {
|
||||
m["appid"] = appId
|
||||
m["nonce"] = guid.S()
|
||||
m["timestamp"] = gtime.Timestamp()
|
||||
var (
|
||||
keyArray = garray.NewSortedStrArrayFrom(gutil.Keys(m))
|
||||
sigContent string
|
||||
)
|
||||
keyArray.Iterator(func(k int, v string) bool {
|
||||
sigContent += v
|
||||
sigContent += gconv.String(m[v])
|
||||
return true
|
||||
})
|
||||
m["signature"] = gmd5.MustEncryptString(gmd5.MustEncryptString(sigContent) + appSecret)
|
||||
jsonContent, _ = json.Marshal(m)
|
||||
}
|
||||
return jsonContent
|
||||
}
|
||||
|
||||
func main() {
|
||||
c := g.Client()
|
||||
c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) {
|
||||
bodyBytes, _ := ioutil.ReadAll(r.Body)
|
||||
if len(bodyBytes) > 0 {
|
||||
// 注入签名相关参数,修改Request原有的提交参数
|
||||
bodyBytes = injectSignature(bodyBytes)
|
||||
r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||
r.ContentLength = int64(len(bodyBytes))
|
||||
}
|
||||
return c.Next(r)
|
||||
})
|
||||
content := c.ContentJson().PostContent("http://127.0.0.1:8199/", g.Map{
|
||||
"name": "goframe",
|
||||
"site": "https://goframe.org",
|
||||
})
|
||||
fmt.Println(content)
|
||||
}
|
||||
17
.example/net/ghttp/client/middleware/server.go
Normal file
17
.example/net/ghttp/client/middleware/server.go
Normal file
@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/frame/g"
|
||||
"github.com/gogf/gf/net/ghttp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := g.Server()
|
||||
s.Group("/", func(group *ghttp.RouterGroup) {
|
||||
group.ALL("/", func(r *ghttp.Request) {
|
||||
r.Response.Write(r.GetMap())
|
||||
})
|
||||
})
|
||||
s.SetPort(8199)
|
||||
s.Run()
|
||||
}
|
||||
@ -25,7 +25,7 @@ func main() {
|
||||
//fmt.Println(r.GetBody())
|
||||
if err := r.Parse(&req); err != nil {
|
||||
// Validation error.
|
||||
if v, ok := err.(*gvalid.Error); ok {
|
||||
if v, ok := err.(gvalid.Error); ok {
|
||||
r.Response.WriteJsonExit(RegisterRes{
|
||||
Code: 1,
|
||||
Error: v.FirstString(),
|
||||
|
||||
@ -24,7 +24,7 @@ func main() {
|
||||
var req *RegisterReq
|
||||
if err := r.Parse(&req); err != nil {
|
||||
// Validation error.
|
||||
if v, ok := err.(*gvalid.Error); ok {
|
||||
if v, ok := err.(gvalid.Error); ok {
|
||||
r.Response.WriteJsonExit(RegisterRes{
|
||||
Code: 1,
|
||||
Error: v.FirstString(),
|
||||
|
||||
@ -339,7 +339,7 @@ func New(group ...string) (db DB, err error) {
|
||||
defer configs.RUnlock()
|
||||
|
||||
if len(configs.config) < 1 {
|
||||
return nil, gerror.New("empty database configuration")
|
||||
return nil, gerror.New("database configuration is empty, please set the database configuration before using")
|
||||
}
|
||||
if _, ok := configs.config[groupName]; ok {
|
||||
if node, err := getConfigNodeByGroup(groupName, true); err == nil {
|
||||
@ -358,13 +358,19 @@ func New(group ...string) (db DB, err error) {
|
||||
}
|
||||
return c.db, nil
|
||||
} else {
|
||||
return nil, gerror.New(fmt.Sprintf(`unsupported database type "%s"`, node.Type))
|
||||
return nil, gerror.Newf(
|
||||
`cannot find database driver for specified database type "%s", did you misspell type name "%s" or forget importing the database driver?`,
|
||||
node.Type, node.Type,
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, gerror.New(fmt.Sprintf(`database configuration node "%s" is not found`, groupName))
|
||||
return nil, gerror.Newf(
|
||||
`database configuration node "%s" is not found, did you misspell group name "%s" or miss the database configuration?`,
|
||||
groupName, groupName,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -54,14 +54,14 @@ func Database(name ...string) gdb.DB {
|
||||
if exampleConfigFilePath, _ := Config().GetFilePath(exampleFileName); exampleConfigFilePath != "" {
|
||||
panic(gerror.Wrapf(
|
||||
err,
|
||||
`configuration file "%s" not found, but found "%s", did you miss renaming the configuration example file?`,
|
||||
`configuration file "%s" not found, but found "%s", did you miss renaming the example configuration file?`,
|
||||
Config().GetFileName(),
|
||||
exampleFileName,
|
||||
))
|
||||
} else {
|
||||
panic(gerror.Wrapf(
|
||||
err,
|
||||
`configuration file "%s" not found, did you miss the configuration file or the file name setting?`,
|
||||
`configuration file "%s" not found, did you miss the configuration file or the misspell the configuration file name?`,
|
||||
Config().GetFileName(),
|
||||
))
|
||||
}
|
||||
|
||||
@ -41,7 +41,6 @@ func TranslateFormat(ctx context.Context, format string, values ...interface{})
|
||||
}
|
||||
|
||||
// Translate translates <content> with configured language and returns the translated content.
|
||||
// The parameter <language> specifies custom translation language ignoring configured language.
|
||||
func Translate(ctx context.Context, content string) string {
|
||||
return Instance().Translate(ctx, content)
|
||||
}
|
||||
|
||||
@ -138,7 +138,6 @@ func (m *Manager) TranslateFormat(ctx context.Context, format string, values ...
|
||||
}
|
||||
|
||||
// Translate translates <content> with configured language.
|
||||
// The parameter <language> specifies custom translation language ignoring configured language.
|
||||
func (m *Manager) Translate(ctx context.Context, content string) string {
|
||||
m.init()
|
||||
m.mu.RLock()
|
||||
|
||||
@ -189,7 +189,7 @@ var (
|
||||
// string/map/struct/*struct.
|
||||
// The optional parameter `params` specifies the extra validation parameters for some rules
|
||||
// like: required-*、same、different, etc.
|
||||
func Check(ctx context.Context, value interface{}, rules string, messages interface{}, params ...interface{}) *Error {
|
||||
func Check(ctx context.Context, value interface{}, rules string, messages interface{}, params ...interface{}) Error {
|
||||
return defaultValidator.Ctx(ctx).Check(value, rules, messages, params...)
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ func Check(ctx context.Context, value interface{}, rules string, messages interf
|
||||
// The parameter `rules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// if `rules` is type of []string.
|
||||
// The optional parameter `messages` specifies the custom error messages for specified keys and rules.
|
||||
func CheckMap(ctx context.Context, params interface{}, rules interface{}, messages ...CustomMsg) *Error {
|
||||
func CheckMap(ctx context.Context, params interface{}, rules interface{}, messages ...CustomMsg) Error {
|
||||
return defaultValidator.Ctx(ctx).CheckMap(params, rules, messages...)
|
||||
}
|
||||
|
||||
@ -208,7 +208,7 @@ func CheckMap(ctx context.Context, params interface{}, rules interface{}, messag
|
||||
// The parameter `rules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// if `rules` is type of []string.
|
||||
// The optional parameter `messages` specifies the custom error messages for specified keys and rules.
|
||||
func CheckStruct(ctx context.Context, object interface{}, rules interface{}, messages ...CustomMsg) *Error {
|
||||
func CheckStruct(ctx context.Context, object interface{}, rules interface{}, messages ...CustomMsg) Error {
|
||||
return defaultValidator.Ctx(ctx).CheckStruct(object, rules, messages...)
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ func CheckStruct(ctx context.Context, object interface{}, rules interface{}, mes
|
||||
// The parameter `rules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// if `rules` is type of []string.
|
||||
// The optional parameter `messages` specifies the custom error messages for specified keys and rules.
|
||||
func CheckStructWithParamMap(ctx context.Context, object interface{}, paramMap interface{}, rules interface{}, messages ...CustomMsg) *Error {
|
||||
func CheckStructWithParamMap(ctx context.Context, object interface{}, paramMap interface{}, rules interface{}, messages ...CustomMsg) Error {
|
||||
return defaultValidator.Ctx(ctx).CheckStructWithParamMap(object, paramMap, rules, messages...)
|
||||
}
|
||||
|
||||
|
||||
@ -14,19 +14,28 @@ import (
|
||||
)
|
||||
|
||||
// Error is the validation error for validation result.
|
||||
type Error struct {
|
||||
rules []string // Rules by sequence, which is used for keeping error sequence.
|
||||
errors ErrorMap // Error map.
|
||||
firstKey string // The first error rule key(nil in default).
|
||||
firstItem map[string]string // The first error rule value(nil in default).
|
||||
type Error interface {
|
||||
Current() error
|
||||
Error() string
|
||||
FirstItem() (key string, messages map[string]string)
|
||||
FirstRule() (rule string, err string)
|
||||
FirstString() (err string)
|
||||
Map() map[string]string
|
||||
Maps() map[string]map[string]string
|
||||
String() string
|
||||
Strings() (errs []string)
|
||||
}
|
||||
|
||||
// ErrorMap is the validation error map:
|
||||
// map[field]map[rule]message
|
||||
type ErrorMap map[string]map[string]string
|
||||
// validationError is the validation error for validation result.
|
||||
type validationError struct {
|
||||
rules []string // Rules by sequence, which is used for keeping error sequence.
|
||||
errors map[string]map[string]string // Error map:map[field]map[rule]message
|
||||
firstKey string // The first error rule key(nil in default).
|
||||
firstItem map[string]string // The first error rule value(nil in default).
|
||||
}
|
||||
|
||||
// newError creates and returns a validation error.
|
||||
func newError(rules []string, errors map[string]map[string]string) *Error {
|
||||
func newError(rules []string, errors map[string]map[string]string) *validationError {
|
||||
for field, m := range errors {
|
||||
for k, v := range m {
|
||||
v = strings.Replace(v, ":attribute", field, -1)
|
||||
@ -36,14 +45,14 @@ func newError(rules []string, errors map[string]map[string]string) *Error {
|
||||
}
|
||||
errors[field] = m
|
||||
}
|
||||
return &Error{
|
||||
return &validationError{
|
||||
rules: rules,
|
||||
errors: errors,
|
||||
}
|
||||
}
|
||||
|
||||
// newErrorStr creates and returns a validation error by string.
|
||||
func newErrorStr(key, err string) *Error {
|
||||
func newErrorStr(key, err string) *validationError {
|
||||
return newError(nil, map[string]map[string]string{
|
||||
"__gvalid__": {
|
||||
key: err,
|
||||
@ -52,7 +61,7 @@ func newErrorStr(key, err string) *Error {
|
||||
}
|
||||
|
||||
// Map returns the first error message as map.
|
||||
func (e *Error) Map() map[string]string {
|
||||
func (e *validationError) Map() map[string]string {
|
||||
if e == nil {
|
||||
return map[string]string{}
|
||||
}
|
||||
@ -61,7 +70,7 @@ func (e *Error) Map() map[string]string {
|
||||
}
|
||||
|
||||
// Maps returns all error messages as map.
|
||||
func (e *Error) Maps() ErrorMap {
|
||||
func (e *validationError) Maps() map[string]map[string]string {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
@ -69,7 +78,7 @@ func (e *Error) Maps() ErrorMap {
|
||||
}
|
||||
|
||||
// FirstItem returns the field name and error messages for the first validation rule error.
|
||||
func (e *Error) FirstItem() (key string, messages map[string]string) {
|
||||
func (e *validationError) FirstItem() (key string, messages map[string]string) {
|
||||
if e == nil {
|
||||
return "", map[string]string{}
|
||||
}
|
||||
@ -97,7 +106,7 @@ func (e *Error) FirstItem() (key string, messages map[string]string) {
|
||||
}
|
||||
|
||||
// FirstRule returns the first error rule and message string.
|
||||
func (e *Error) FirstRule() (rule string, err string) {
|
||||
func (e *validationError) FirstRule() (rule string, err string) {
|
||||
if e == nil {
|
||||
return "", ""
|
||||
}
|
||||
@ -127,7 +136,7 @@ func (e *Error) FirstRule() (rule string, err string) {
|
||||
|
||||
// FirstString returns the first error message as string.
|
||||
// Note that the returned message might be different if it has no sequence.
|
||||
func (e *Error) FirstString() (err string) {
|
||||
func (e *validationError) FirstString() (err string) {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
@ -136,7 +145,7 @@ func (e *Error) FirstString() (err string) {
|
||||
}
|
||||
|
||||
// Current is alis of FirstString, which implements interface gerror.ApiCurrent.
|
||||
func (e *Error) Current() error {
|
||||
func (e *validationError) Current() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
@ -145,7 +154,7 @@ func (e *Error) Current() error {
|
||||
}
|
||||
|
||||
// String returns all error messages as string, multiple error messages joined using char ';'.
|
||||
func (e *Error) String() string {
|
||||
func (e *validationError) String() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
@ -153,7 +162,7 @@ func (e *Error) String() string {
|
||||
}
|
||||
|
||||
// Error implements interface of error.Error.
|
||||
func (e *Error) Error() string {
|
||||
func (e *validationError) Error() string {
|
||||
if e == nil {
|
||||
return ""
|
||||
}
|
||||
@ -161,7 +170,7 @@ func (e *Error) Error() string {
|
||||
}
|
||||
|
||||
// Strings returns all error messages as string array.
|
||||
func (e *Error) Strings() (errs []string) {
|
||||
func (e *validationError) Strings() (errs []string) {
|
||||
if e == nil {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
@ -35,12 +35,12 @@ type apiTime interface {
|
||||
// string/map/struct/*struct.
|
||||
// The optional parameter `params` specifies the extra validation parameters for some rules
|
||||
// like: required-*、same、different, etc.
|
||||
func (v *Validator) Check(value interface{}, rules string, messages interface{}, paramMap ...interface{}) *Error {
|
||||
func (v *Validator) Check(value interface{}, rules string, messages interface{}, paramMap ...interface{}) Error {
|
||||
return v.doCheck("", value, rules, messages, paramMap...)
|
||||
}
|
||||
|
||||
// doCheck does the really rules validation for single key-value.
|
||||
func (v *Validator) doCheck(key string, value interface{}, rules string, messages interface{}, paramMap ...interface{}) *Error {
|
||||
func (v *Validator) doCheck(key string, value interface{}, rules string, messages interface{}, paramMap ...interface{}) Error {
|
||||
// If there's no validation rules, it does nothing and returns quickly.
|
||||
if rules == "" {
|
||||
return nil
|
||||
@ -136,7 +136,7 @@ func (v *Validator) doCheck(key string, value interface{}, rules string, message
|
||||
index++
|
||||
}
|
||||
if len(errorMsgArray) > 0 {
|
||||
return newError([]string{rules}, ErrorMap{
|
||||
return newError([]string{rules}, map[string]map[string]string{
|
||||
key: errorMsgArray,
|
||||
})
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ import (
|
||||
// The parameter `rules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// if `rules` is type of []string.
|
||||
// The optional parameter `messages` specifies the custom error messages for specified keys and rules.
|
||||
func (v *Validator) CheckMap(params interface{}, rules interface{}, messages ...CustomMsg) *Error {
|
||||
func (v *Validator) CheckMap(params interface{}, rules interface{}, messages ...CustomMsg) Error {
|
||||
// If there's no validation rules, it does nothing and returns quickly.
|
||||
if params == nil || rules == nil {
|
||||
return nil
|
||||
@ -25,7 +25,7 @@ func (v *Validator) CheckMap(params interface{}, rules interface{}, messages ...
|
||||
checkRules = make(map[string]string)
|
||||
customMsgs = make(CustomMsg)
|
||||
errorRules = make([]string, 0)
|
||||
errorMaps = make(ErrorMap)
|
||||
errorMaps = make(map[string]map[string]string)
|
||||
)
|
||||
switch v := rules.(type) {
|
||||
// Sequence tag: []sequence tag
|
||||
|
||||
@ -16,10 +16,10 @@ import (
|
||||
// CheckStruct validates struct and returns the error result.
|
||||
//
|
||||
// The parameter `object` should be type of struct/*struct.
|
||||
// The parameter `rules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// The parameter `customRules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// if `rules` is type of []string.
|
||||
// The optional parameter `messages` specifies the custom error messages for specified keys and rules.
|
||||
func (v *Validator) CheckStruct(object interface{}, customRules interface{}, customErrorMessageMap ...CustomMsg) *Error {
|
||||
// The optional parameter `customErrorMessageMap` specifies the custom error messages for specified keys and rules.
|
||||
func (v *Validator) CheckStruct(object interface{}, customRules interface{}, customErrorMessageMap ...CustomMsg) Error {
|
||||
var message CustomMsg
|
||||
if len(customErrorMessageMap) > 0 {
|
||||
message = customErrorMessageMap[0]
|
||||
@ -36,10 +36,11 @@ func (v *Validator) CheckStruct(object interface{}, customRules interface{}, cus
|
||||
// CheckStructWithParamMap validates struct with given parameter map and returns the error result.
|
||||
//
|
||||
// The parameter `object` should be type of struct/*struct.
|
||||
// The parameter `rules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// The parameter `paramMap` should be type of map, which specifies the parameter map used in validation.
|
||||
// The parameter `customRules` can be type of []string/map[string]string. It supports sequence in error result
|
||||
// if `rules` is type of []string.
|
||||
// The optional parameter `messages` specifies the custom error messages for specified keys and rules.
|
||||
func (v *Validator) CheckStructWithParamMap(object interface{}, paramMap interface{}, customRules interface{}, customErrorMessageMap ...CustomMsg) *Error {
|
||||
// The optional parameter `customErrorMessageMap` specifies the custom error messages for specified keys and rules.
|
||||
func (v *Validator) CheckStructWithParamMap(object interface{}, paramMap interface{}, customRules interface{}, customErrorMessageMap ...CustomMsg) Error {
|
||||
var message CustomMsg
|
||||
if len(customErrorMessageMap) > 0 {
|
||||
message = customErrorMessageMap[0]
|
||||
@ -53,10 +54,10 @@ func (v *Validator) CheckStructWithParamMap(object interface{}, paramMap interfa
|
||||
})
|
||||
}
|
||||
|
||||
func (v *Validator) doCheckStructWithParamMap(input *doCheckStructWithParamMapInput) *Error {
|
||||
func (v *Validator) doCheckStructWithParamMap(input *doCheckStructWithParamMapInput) Error {
|
||||
var (
|
||||
// Returning error.
|
||||
errorMaps = make(ErrorMap)
|
||||
errorMaps = make(map[string]map[string]string)
|
||||
)
|
||||
fieldMap, err := structs.FieldMap(input.Object, aliasNameTagPriority, true)
|
||||
if err != nil {
|
||||
@ -77,7 +78,7 @@ func (v *Validator) doCheckStructWithParamMap(input *doCheckStructWithParamMapIn
|
||||
recursiveInput.Object = field.Value
|
||||
if err := v.doCheckStructWithParamMap(&recursiveInput); err != nil {
|
||||
// It merges the errors into single error map.
|
||||
for k, m := range err.errors {
|
||||
for k, m := range err.(*validationError).errors {
|
||||
errorMaps[k] = m
|
||||
}
|
||||
}
|
||||
@ -158,7 +159,8 @@ func (v *Validator) doCheckStructWithParamMap(input *doCheckStructWithParamMapIn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge the custom validation rules with rules in struct tag.
|
||||
// The custom rules has the most high priority that can overwrite the struct tag rules.
|
||||
for _, field := range tagField {
|
||||
fieldName := field.Name()
|
||||
// sequence tag == struct tag
|
||||
|
||||
@ -187,4 +187,6 @@ func ExampleRegisterRule_OverwriteRequired() {
|
||||
// It's required
|
||||
// rule deleted
|
||||
// It's required
|
||||
// <nil>
|
||||
// <nil>
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ func Test_CustomRule2(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
errStr := "data map should not be empty"
|
||||
t.Assert(gvalid.Check(context.TODO(), g.Map{}, rule, errStr).String(), errStr)
|
||||
t.Assert(gvalid.Check(context.TODO(), g.Map{"k": "v"}, rule, errStr).String(), nil)
|
||||
t.Assert(gvalid.Check(context.TODO(), g.Map{"k": "v"}, rule, errStr), nil)
|
||||
})
|
||||
// Error with struct validation.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
@ -121,8 +121,8 @@ func Test_CustomRule_AllowEmpty(t *testing.T) {
|
||||
// Check.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
errStr := "error"
|
||||
t.Assert(gvalid.Check(context.TODO(), "", rule, errStr).String(), "")
|
||||
t.Assert(gvalid.Check(context.TODO(), "gf", rule, errStr).String(), "")
|
||||
t.Assert(gvalid.Check(context.TODO(), "", rule, errStr), nil)
|
||||
t.Assert(gvalid.Check(context.TODO(), "gf", rule, errStr), nil)
|
||||
t.Assert(gvalid.Check(context.TODO(), "gf2", rule, errStr).String(), errStr)
|
||||
})
|
||||
// Error with struct validation.
|
||||
@ -136,7 +136,7 @@ func Test_CustomRule_AllowEmpty(t *testing.T) {
|
||||
Data: "123456",
|
||||
}
|
||||
err := gvalid.CheckStruct(context.TODO(), st, nil)
|
||||
t.Assert(err.String(), "")
|
||||
t.Assert(err, nil)
|
||||
})
|
||||
// No error with struct validation.
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
|
||||
@ -18,7 +18,7 @@ import (
|
||||
|
||||
func TestValidator_I18n(t *testing.T) {
|
||||
var (
|
||||
err *gvalid.Error
|
||||
err gvalid.Error
|
||||
i18nManager = gi18n.New(gi18n.Options{Path: gdebug.TestDataPath("i18n")})
|
||||
ctxCn = gi18n.WithLanguage(context.TODO(), "cn")
|
||||
validator = gvalid.New().I18n(i18nManager)
|
||||
|
||||
Reference in New Issue
Block a user