go-playground / validator

:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
MIT License
16.41k stars 1.31k forks source link

ValidateMap support []interface #1108

Open LjtGentle opened 1 year ago

LjtGentle commented 1 year ago

Package version eg. v10:

json Unmarshal nested map will be []interface not expected []map[string]interface{}, so call ValidateMap will be validation error.

Issue, Question or Enhancement:

Code sample, to showcase or reproduce:

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 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
                }
            } else if dataObjs, ok := data[field].([]map[string]interface{}); ok {
                for _, obj := range dataObjs {
                    err := v.ValidateMapCtx(ctx, obj, ruleObj)
                    if len(err) > 0 {
                        errs[field] = err
                    }
                }
                //Newly added code for my issue
            } else if dataObjs, ok := data[field].([]interface{}); ok {
                if len(dataObjs) > 0 {
                    for _, obj := range dataObjs {
                        objMap, ok := obj.(map[string]interface{})
                        if !ok {
                            errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
                            break
                        }
                        err := v.ValidateMapCtx(ctx, objMap, ruleObj)
                        if len(err) > 0 {
                            errs[field] = err
                        }
                    }

                }
            } else {
                errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
            }
        } else if ruleStr, ok := rule.(string); ok {
            err := v.VarCtx(ctx, data[field], ruleStr)
            if err != nil {
                errs[field] = err
            }
        }
    }
    return errs
}
ikandars commented 8 months ago

Up vote this feature 👍