diff --git a/validator_instance.go b/validator_instance.go index 1a345138..05461b94 100644 --- a/validator_instance.go +++ b/validator_instance.go @@ -232,6 +232,15 @@ func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, callValidationE return v.registerValidation(tag, fn, false, nilCheckable) } +// GetValidation gets the current validation function associated with the given tag +func (v *Validate) GetValidation(tag string) (FuncCtx, bool) { + wrapper, ok := v.validations[tag] + if !ok { + return nil, false + } + return wrapper.fn, wrapper.runValidatinOnNil +} + func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error { if len(tag) == 0 { return errors.New("function Key cannot be empty") diff --git a/validator_test.go b/validator_test.go index ffff4b0d..8dc96a59 100644 --- a/validator_test.go +++ b/validator_test.go @@ -7417,6 +7417,50 @@ func TestValidateByTagAndValue(t *testing.T) { AssertError(t, errs, "", "", "", "", "isequaltestfunc") } +func TestValidationChain(t *testing.T) { + monthNames := [12]string{"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"} + daysInMonth := [12]int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} + + validate := New() + + origFn, origRunOnNil := validate.GetValidation("eq") + NotEqual(t, origFn, nil) + + // A validation function that checks if the value is equal to the number of days in a month + augmentedEq := func(ctx context.Context, fl FieldLevel) bool { + if fl.Field().Kind() == reflect.Int && strings.HasPrefix(fl.Param(), "days-in-") { + daysCount := 0 + for idx, m := range monthNames { + if fl.Param()[8:] == m { + daysCount = daysInMonth[idx] + break + } + } + if daysCount > 0 && fl.Field().Int() == int64(daysCount) { + return true + } + return false + } + + // The value and parameter are not comparable by us so next to the next link in the chain + if fl.Field().Kind() != reflect.Invalid || origRunOnNil { + return origFn(ctx, fl) + } + return false + } + errs := validate.RegisterValidationCtx("eq", augmentedEq) + Equal(t, errs, nil) + + val := 31 + field := "test" + + errs = validate.VarWithValue(val, field, "eq=days-in-march") + Equal(t, errs, nil) + + errs = validate.VarWithValue(val, field, "eq=days-in-april") + NotEqual(t, errs, nil) +} + func TestAddFunctions(t *testing.T) { fn := func(fl FieldLevel) bool { return true