Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for mutually exclusive groups of validations chained with OR #1280

Open
2 tasks done
adam-shamaa opened this issue Jun 13, 2024 · 0 comments
Open
2 tasks done

Comments

@adam-shamaa
Copy link

adam-shamaa commented Jun 13, 2024

  • I have looked at the documentation here first?
  • I have looked at the examples provided that may showcase my question here?

Package version eg. v9, v10:

v10

Issue, Question or Enhancement:

I'd like to define groups of validations from existing rules and chain them together with an OR clause. Something along the lines of

var req struct {
	Email string `validate:"(bakedin_tag1,bakedin_tag2)|bakedin_tag3"`
}

The syntax above of using parentheses/brackets isn't supported so I've tried defining an alias for the (bakedin_tag_1, bakedin_tag_2) clause:

validate.RegisterAlias("lcase_email", "email,lowercase")

However, there's a bug where aliases can't be used with an OR operator (existing issue for this #766)

Seem like the only route would be avoiding an alias and defining a custom validator function which validates the email and lowercase rule. But I want to avoid this as I'd be re-creating the baked-in validation methods isEmail and isLowerCase

validator/baked_in.go

Lines 1675 to 1678 in a947377

// isEmail is the validation function for validating if the current field's value is a valid email address.
func isEmail(fl FieldLevel) bool {
return emailRegex().MatchString(fl.Field().String())
}

validator/baked_in.go

Lines 2707 to 2719 in a947377

// isLowercase is the validation function for validating if the current field's value is a lowercase string.
func isLowercase(fl FieldLevel) bool {
field := fl.Field()
if field.Kind() == reflect.String {
if field.String() == "" {
return false
}
return field.String() == strings.ToLower(field.String())
}
panic(fmt.Sprintf("Bad field type %T", field.Interface()))
}
As these methods are private to the validator package so I can't reference them.

Code sample, to showcase or reproduce:

package main

import (
	"github.com/go-playground/validator/v10"
)

type Example struct {
	Email string `validate:"lcase_email|empty_string"`
}

func main() {
	validate := validator.New()
	validate.RegisterAlias("lcase_email", "email,lowercase")
	validate.RegisterAlias("empty_string", "eq=")

	ex := &Example{
		Email: "[email protected]",
	}

	err := validate.Struct(ex)
	if err != nil {
		println(err.Error())
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant