Skip to content

Instantly share code, notes, and snippets.

@ZenGround0
Last active January 21, 2020 07:34
Show Gist options
  • Save ZenGround0/a41841694c87b5e04e4fab0dd20a9a5c to your computer and use it in GitHub Desktop.
Save ZenGround0/a41841694c87b5e04e4fab0dd20a9a5c to your computer and use it in GitHub Desktop.
Atlas on type causing refmt stack overflow
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()
// 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