go-ozzo / ozzo-validation

An idiomatic Go (golang) validation package. Supports configurable and extensible validation rules (validators) using normal language constructs instead of error-prone struct tags.
MIT License
3.73k stars 224 forks source link

Custom validation rule with additional parameters #64

Closed wI2L closed 5 years ago

wI2L commented 5 years ago

Hello

The validation.By method offers no way to use additional parameters. I would like to modify it to accept a varidic list of parameters after the value to validate, like so:

func checkAbc(value interface{}, args ...interface{}) error {
    s, _ := value.(string)
        caseSensitive, _ := args[0].(bool)
    if !caseSensitive && s != "abc" {
        return errors.New("must be abc")
    }
    if caseSensitive && !EqualFold(s, "abc") {
        return errors.New("must be abc")
    }
    return nil
}

err := validation.Validate("xyz", validation.By(checkAbc, true))

What do you think about it ?

burner-account commented 5 years ago

Please forgive my stackoverflow-like usage of github.

My initial idea would be to not modify the 'validation.By' signature but to wrap your custom rule function.

func buildCheckABC(args ...interface{}) {
    return func checkAbc(value interface{}) error {
       // do something with 'args' and 'value'
    }
}

And then call it somewhat like

err := validation.Validate("xyz", validation.By( buildCheckABC(arg1, arg2)))

Just an idea, not tested at all.

ghost commented 5 years ago

I tried the same but it create cyclic import issue if I send the whole struct. (Possible way to send each field separately and handled the same in return func) In my case, I need to validate a field by creating a HMAC using the other fields in the same struct and compare the same against the filed passed for validation.

LindseyB commented 5 years ago

I'm running into the same issue, has anyone figure out a solution for this?

qiangxue commented 5 years ago

Have you tried @burner-account's suggestion? It should work.

LindseyB commented 5 years ago

Oh that does work @qiangxue, thanks do you think its worth wile to add docs for this?

qiangxue commented 5 years ago

This is a typical usage of using closure to parameterize a function. But yes, it doesn't hurt to add an example to the docs.