The task is pretty simple. I have struct for model Foo, and one for it's representation:
type Foo struct {
FooId string
Bar string
Baz *string
Salt int64
}
type FooView struct {
FooId *string `json: "foo_id"`
Bar *string `json: "bar"`
Baz *string `json: "baz"`
}
As you may see, there is Salt field which I want to hide, change JSON field names, and do all the fields optional. The target method should fill FooView using Foo like this:
func MirrorFoo(foo Foo) (*FooView, error) {
return &FooView{
FooId: &foo.FooId,
Bar: &foo.Bar,
Baz: foo.Baz,
}, nil
}
And now, I want to do the same with Go reflect:
func Mirror(src interface{}, dstType reflect.Type) (interface{}, error) {
zeroValue := reflect.Value{}
srcValue := reflect.ValueOf(src)
srcType := srcValue.Type()
dstValue := reflect.New(dstType)
dstValueElem := dstValue.Elem()
for i := 0; i < srcType.NumField(); i++ {
srcTypeField := srcType.Field(i)
srcValueField := srcValue.FieldByName(srcTypeField.Name)
dstField := dstValueElem.FieldByName(srcTypeField.Name)
// if current source field exists in destination type
if dstField != zeroValue {
srcValueField := srcValue.Field(i)
if dstField.Kind() == reflect.Ptr && srcValueField.Kind() != reflect.Ptr {
panic("???")
} else {
dstField.Set(srcValueField)
}
}
}
return dstValue.Interface(), nil
}
This code works fine when FooId is uuid.UUID in both types, but it fails when source is uuid.UUID and destination is *uuid.UUID, and now do not know how to overcome this.
Somehow I need to do analog of dstField.Set(reflect.ValueOf(&uuid.UUID{}...)) bit everything I've tried does not works. Any ideas?
Aucun commentaire:
Enregistrer un commentaire