could you help me understand if this is doable in Go?
I have those 2 structs and i really need to do the validation (later) this way:
type Parent struct {
Sth string `fatvalid:"required"`
SthElse string `fatvalid:"required"`
Children []*Child
Sth_Fatvalid string
SthElse_Fatvalid string
}
type Child struct {
ChildName string `fatvalid:"required"`
ChildAge uint `fatvalid:"required"`
ChildName_Fatvalid string
ChildAge_Fatvalid string
}
Then i have this function that should recursively go through each field of the "Parent" struct and all the Child structs and do some validation by setting the appropriate message on the "_Fatvalid" fields:
(i took the original code from http://ift.tt/2iTSepw and tried to make it work for me)
func Fatvalid(iface interface{}) error {
ifv := reflect.ValueOf(iface)
if ifv.Kind() != reflect.Ptr {
return errors.New("Not a pointer")
}
ift := reflect.Indirect(ifv).Type()
for i := 0; i < ift.NumField(); i++ {
v := ift.Field(i)
if strings.HasSuffix(v.Name, "_Fatvalid") {
continue
}
el := reflect.Indirect(ifv.Elem().FieldByName(v.Name))
el_validation := reflect.Indirect(ifv.Elem().FieldByName(v.Name + "_Fatvalid"))
switch el.Kind() {
case reflect.String:
if el_validation.CanSet() {
fmt.Println("obrabiam: ", v.Name)
el_validation.SetString("This validation returns error!")
}
case reflect.Slice:
if slice, ok := el.Interface().([]*Child); ok {
for _, input := range slice {
Fatvalid(input)
}
}
}
}
return nil
}
And now i really want to learn how to change this bit:
if slice, ok := el.Interface().([]*Child); ok {
for _, input := range slice {
Fatvalid(input)
}
}
...so that i don't have to hardcode cast of the type on the interface like that ([]*Child) but to use the reflection to do that for me. Is this possible?
I know that the whole idea of doing a validation this way looks strange but i really need to have it this way because otherwise it complicates so many other things.
Aucun commentaire:
Enregistrer un commentaire