Last active
January 21, 2020 07:34
-
-
Save ZenGround0/a41841694c87b5e04e4fab0dd20a9a5c to your computer and use it in GitHub Desktop.
Atlas on type causing refmt stack overflow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var blockAtlasEntry = atlas.BuildEntry(Block{}).Transform(). | |
TransformMarshal(func(liveForm reflect.Value) (serialForm reflect.Value, err error) { | |
return StructToTuple(liveForm) | |
}, reflect.TypeOf([]interface{}{})). | |
TransformUnmarshal(func(serialForm reflect.Value) (liveForm reflect.Value, err error) { | |
return TupleToStruct(serialForm, reflect.TypeOf(Block{})) | |
}, reflect.TypeOf(Block{})). | |
Complete() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// StructToTuple Converts any struct value to an []interface{}{} value where the ith slice | |
// element is the ith public field. | |
func StructToTuple(val reflect.Value) (reflect.Value, error) { | |
if val.Kind() != reflect.Struct { | |
return reflect.ValueOf(nil), fmt.Errorf("struct to tuple expects struct") | |
} | |
n := val.NumField() | |
tuple := make([]interface{}, 0) | |
for i := 0; i < n; i++ { | |
f := val.Field(i) | |
if f.CanInterface() { // only exported fields | |
tuple = append(tuple, f.Interface()) | |
} | |
} | |
return reflect.ValueOf(tuple), nil | |
} | |
// TupleToStruct Converts an []interface{}{} value to a struct value where the ith public | |
// field is set to the ith slice element. | |
func TupleToStruct(tupleVal reflect.Value, structType reflect.Type) (reflect.Value, error) { | |
structPtrVal := reflect.New(structType) | |
structVal := structPtrVal.Elem() | |
if structVal.Kind() != reflect.Struct { | |
return reflect.ValueOf(nil), fmt.Errorf("TupleToStruct expects struct type") | |
} | |
if tupleVal.Type() != reflect.TypeOf([]interface{}{}) { | |
return reflect.ValueOf(nil), fmt.Errorf("TupleToStruct expects []interface{} value") | |
} | |
n := structVal.NumField() | |
j := 0 // total tuple values consumed | |
for i := 0; i < n; i++ { | |
f := structVal.Field(i) | |
if f.CanInterface() { // only exported fields | |
tupleI := tupleVal.Index(j) | |
f.Set(tupleI.Elem()) | |
j++ | |
} | |
} | |
return structVal, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment