Open RobinVdBroeck opened 3 years ago
Hey, I found that I could address this with my own helper like this:
func Nested(target interface{}, fieldRules ...*validation.FieldRules) *validation.FieldRules {
return validation.Field(target, validation.By(func(value interface{}) error {
valueV := reflect.Indirect(reflect.ValueOf(value))
if valueV.CanAddr() {
addr := valueV.Addr().Interface()
return validation.ValidateStruct(addr, fieldRules...)
}
return validation.ValidateStruct(target, fieldRules...)
}))
}
To use it I can do this:
wrapper := Wrapper{
Attr1: 6,
FieldOne: Foo{
FieldThree: "Test",
FieldFour: "",
},
FieldTwo: &Bar{
FieldFive: 16,
},
}
err := validation.ValidateStruct(&wrapper,
validation.Field(&wrapper.Attr1, validation.Required),
Nested(&wrapper.FieldOne,
validation.Field(&wrapper.FieldOne.FieldThree, validation.Required),
validation.Field(&wrapper.FieldOne.FieldFour, validation.Required),
),
Nested(&wrapper.FieldTwo,
validation.Field(&wrapper.FieldTwo.FieldFive, validation.Required, validation.Max(10)),
),
)
Here's a playground link based on your initial example: https://play.golang.org/p/oLUVw6cikws
Haven't used it much so can't guarantee it's bug free, but seems to work as intended.
@ki4jnq to access FieldFive
, you may get nil pointer panic
@ki4jnq to access
FieldFive
, you may get nil pointer panic
You mean when doing this: &wrapper.FieldTwo.FieldFive
? True, your code would have to check that manually if it's a concern.
I would love for it to be possible to validate a field that is deeply nested. You can find an example of what I mean at: https://play.golang.org/p/bVjDNqkVzQj
In my use case, adding a Validate() function to the nested struct is not possible. The validation of the nested struct is not always the same, and depends on some external factors.