From 188d9611c9dcd6cef535ea530a58383089abe02a Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Wed, 20 Jan 2021 00:47:13 +0300 Subject: [PATCH] util/reflect: add struct field helper Signed-off-by: Vasiliy Tolstov --- util/reflect/reflect.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/util/reflect/reflect.go b/util/reflect/reflect.go index dcac5d45..c38003ef 100644 --- a/util/reflect/reflect.go +++ b/util/reflect/reflect.go @@ -49,3 +49,35 @@ func Zero(src interface{}) (interface{}, error) { return dst.Interface(), nil } + +func StructFields(src interface{}) ([]reflect.StructField, error) { + var fields []reflect.StructField + + sv := reflect.ValueOf(src) + if sv.Kind() == reflect.Ptr { + sv = sv.Elem() + } + if sv.Kind() != reflect.Struct { + return nil, ErrInvalidStruct + } + + typ := sv.Type() + for idx := 0; idx < typ.NumField(); idx++ { + fld := typ.Field(idx) + val := sv.Field(idx) + if !val.CanSet() || len(fld.PkgPath) != 0 { + continue + } + if val.Kind() == reflect.Struct { + infields, err := StructFields(val.Interface()) + if err != nil { + return nil, err + } + fields = append(fields, infields...) + } else { + fields = append(fields, fld) + } + } + + return fields, nil +}