-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
required_without
and excluded_with
issues with nested structs
#1325
Comments
I created some more tests to get more data. package main
import (
"fmt"
"github.com/go-playground/validator/v10"
)
// NoPointer structure will hold either the Fire or the Water struct, but not both.
type NoPointer struct {
// these validate tags are basically an XOR between Fire and Water
Fire Fire `validate:"required_without=Water,excluded_with=Water"`
Water Water `validate:"required_without=Fire,excluded_with=Fire"`
}
type Pointer struct {
// these validate tags are basically an XOR between Fire and Water
Fire *Fire `validate:"required_without=Water,excluded_with=Water"`
Water *Water `validate:"required_without=Fire,excluded_with=Fire"`
}
// Fire structure holds a URL.
type Fire struct {
MyString string
}
var fire = Fire{
MyString: "test",
}
// Water structure holds a string.
type Water struct {
MyOtherString string
}
var water = Water{
MyOtherString: "123abcd",
}
type NoPointerInnerValidations struct {
// these validate tags are basically an XOR between Earth and Air
Earth Earth `validate:"required_without=Air,excluded_with=Air"`
Air Air `validate:"required_without=Earth,excluded_with=Earth"`
}
type PointerInnerValidations struct {
// these validate tags are basically an XOR between Earth and Air
Earth *Earth `validate:"required_without=Air,excluded_with=Air"`
Air *Air `validate:"required_without=Earth,excluded_with=Earth"`
}
type Earth struct {
MyURLString string `validate:"required,url"`
}
var earth = Earth{
MyURLString: "missingProtocol.www.google.com",
}
type Air struct {
MyUUIDString string `validate:"required,uuid"`
}
var air = Air{
MyUUIDString: "not a uuid",
}
func main() {
v := validator.New()
fmt.Println("========================================")
fmt.Println("Test No Pointer")
testNoPointer(v)
fmt.Println("========================================")
fmt.Println("Test Pointer")
testPointer(v)
fmt.Println("========================================")
fmt.Println("Test No Pointer with inner validations")
testNoPointerInnerValidations(v)
fmt.Println("========================================")
fmt.Println("Test Pointer with inner validations")
testPointerInnerValidations(v)
}
func testNoPointer(v *validator.Validate) {
fmt.Println("Neither set: should fail on required_without")
fmt.Println(v.Struct(&NoPointer{Fire: Fire{}, Water: Water{}})) // should fail on required_without
fmt.Println()
// Apparently required_without doesn't work with zero_value struct, only nil.
fmt.Println("Only Fire set: should pass")
fmt.Println(v.Struct(&NoPointer{Fire: fire, Water: Water{}})) // should pass
fmt.Println()
fmt.Println("Only Water set: should pass")
fmt.Println(v.Struct(&NoPointer{Fire: Fire{}, Water: water})) // should pass
fmt.Println()
fmt.Println("Both set: should fail on excluded_with")
fmt.Println(v.Struct(&NoPointer{Fire: fire, Water: water})) // should fail on excluded_with
fmt.Println()
// Excluded_with does not seem to work with structs.
}
func testPointer(v *validator.Validate) {
fmt.Println("Neither set: should fail on required_without")
fmt.Println(v.Struct(&Pointer{Fire: nil, Water: nil})) // should fail on required_without
fmt.Println()
// Required_without works here.
fmt.Println("Only Fire set: should pass")
fmt.Println(v.Struct(&Pointer{Fire: &fire, Water: nil})) // should pass
fmt.Println()
fmt.Println("Only Water set: should pass")
fmt.Println(v.Struct(&Pointer{Fire: nil, Water: &water})) // should pass
fmt.Println()
fmt.Println("Both set: should fail on excluded_with")
fmt.Println(v.Struct(&Pointer{Fire: &fire, Water: &water})) // should fail on excluded_with
fmt.Println()
// Excluded_with does not seem to work with structs.
}
func testNoPointerInnerValidations(v *validator.Validate) {
fmt.Println("Neither set: should fail only on required_without")
fmt.Println(v.Struct(&NoPointerInnerValidations{Earth: Earth{}, Air: Air{}})) // should fail on required_without
fmt.Println()
fmt.Println("Only Earth set: should fail only on url validation")
fmt.Println(v.Struct(&NoPointerInnerValidations{Earth: earth, Air: Air{}})) // should fail only on url validation
fmt.Println()
fmt.Println("Only Air set: should fail only on uuid validation")
fmt.Println(v.Struct(&NoPointerInnerValidations{Earth: Earth{}, Air: air})) // should fail only on uuid validation
fmt.Println()
fmt.Println("Both set: should fail only on excluded_with")
fmt.Println(v.Struct(&NoPointerInnerValidations{Earth: earth, Air: air})) // should fail on excluded_with
fmt.Println()
// this whole block fails because inner validations run every time, even for zero value structs.
}
func testPointerInnerValidations(v *validator.Validate) {
fmt.Println("Neither set: should fail only on required_without")
fmt.Println(v.Struct(&PointerInnerValidations{Earth: nil, Air: nil})) // should fail on required_without
fmt.Println()
fmt.Println("Only Earth set: should fail only on url validation")
fmt.Println(v.Struct(&PointerInnerValidations{Earth: &earth, Air: nil})) // should fail only on url validation
fmt.Println()
fmt.Println("Only Air set: should fail only on uuid validation")
fmt.Println(v.Struct(&PointerInnerValidations{Earth: nil, Air: &air})) // should fail only on uuid validation
fmt.Println()
fmt.Println("Both set: should fail only on excluded_with")
fmt.Println(v.Struct(&PointerInnerValidations{Earth: &earth, Air: &air})) // should fail on excluded_with
fmt.Println()
// Excluded_with does not seem to work with structs.
// If excluded_with worked with structs this would be correct.
} Output:
|
Results seem to be that I'm not sure what the intention is supposed to be, but inner struct validations run even if it's a empty struct, which means I'd have to use pointers to inner struct types, forcing me to make |
required_without
and excluded_with
don't seem to do anything on nested structsrequired_without
and excluded_with
issues with nested structs
Package version eg. v9, v10:
v10
Issue, Question or Enhancement:
I am working on some code and trying to make two structs XOR'd with each other. As I understand the validations, I should be able to use
required_without
andexcluded_with
to make this happen, but they don't seem to do anything?Code sample, to showcase or reproduce:
Output:
The text was updated successfully, but these errors were encountered: