From 3cac6d154de49343327c3844a3a471f33014cfdd Mon Sep 17 00:00:00 2001 From: hzy Date: Mon, 3 Jul 2023 16:43:49 +0800 Subject: [PATCH] struct can be null flag --- validator_instance.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/validator_instance.go b/validator_instance.go index 7d73711..ccf4aa6 100644 --- a/validator_instance.go +++ b/validator_instance.go @@ -150,17 +150,29 @@ func (v *Validate) SetTagName(name string) { v.tagName = name } +const omitemptyStructPrefix = "__omitempty_struct__" + // ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual // validation validation information via context.Context. func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} { errs := make(map[string]interface{}) for field, rule := range rules { + if strings.HasPrefix(field, omitemptyStructPrefix) == true { + continue + } if ruleObj, ok := rule.(map[string]interface{}); ok { - if dataObj, ok := data[field].(map[string]interface{}); ok { - err := v.ValidateMapCtx(ctx, dataObj, ruleObj) - if len(err) > 0 { - errs[field] = err + if dataObj, ok := data[field]; ok { + if do, ok := dataObj.(map[string]interface{}); ok { + err := v.ValidateMapCtx(ctx, do, ruleObj) + if len(err) > 0 { + errs[field] = err + } + } else { + errs[field] = errors.New("The field: '" + field + "' is not a map to dive") } + } else if _, ok := rules[fmt.Sprintf("%s%s", omitemptyStructPrefix, field)].(string); ok { + // struct can be null + continue } else { errs[field] = errors.New("The field: '" + field + "' is not a map to dive") }