Skip to content

Instantly share code, notes, and snippets.

@unsafe9
Created February 26, 2020 05:36
Show Gist options
  • Save unsafe9/2abc3a90e827481e458ed1715efd009e to your computer and use it in GitHub Desktop.
Save unsafe9/2abc3a90e827481e458ed1715efd009e to your computer and use it in GitHub Desktop.
go struct field expand
package main
import (
"fmt"
"reflect"
)
func GetExpanded(ptr interface{}) (interface{}, error) {
expValue := reflect.ValueOf(ptr).Elem()
t := expValue.Type()
numFields := t.NumField()
for i := 0; i < numFields; i++ {
expFuncName := t.Field(i).Tag.Get("expand")
if "" == expFuncName {
continue
}
expFunc := expValue.MethodByName(expFuncName)
if !expFunc.IsValid() {
return nil, fmt.Errorf("expand failed")
}
returns := expFunc.Call(nil)
if len(returns) == 0 {
panic("expFunc has no returns")
} else if len(returns) == 1 {
// success
} else if err, isError := returns[1].Interface().(error); isError && err != nil {
return nil, err
}
// apply
expValue.Field(i).Set(returns[0])
}
return ptr, nil
}
package main
import (
"fmt"
"encoding/json"
)
func main() {
test := Test{
TestField: map[string]Simplified{
"test": Simplified{},
"test2": Simplified{},
},
}
expanded := TestExpanded{Test: &test,}
GetExpanded(&expanded)
bytes, _ := json.Marshal(&expanded)
fmt.Printf("expanded : %s", string(bytes))
}
package main
// db saving data
type Simplified struct {
Field1 string `json:"field1"`
Field2 string `json:"field2"`
}
// for response to client
type Detail struct {
Simplified
Field3 string `json:"field3"`
}
// container
type Test struct {
TestField map[string]Simplified `json:"test_field"`
}
// expanded container
type TestExpanded struct {
*Test
TestField map[string]Detail `json:"test_field" expand:"GetDetails"`
}
func (t *Test) GetDetails() (map[string]Detail, error) {
details := make(map[string]Detail)
for k, v := range t.TestField {
details[k] = Detail{
Simplified: v,
Field3: "expand test",
}
}
return details, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment