Skip to content

Commit

Permalink
Marshal hierarchical structs
Browse files Browse the repository at this point in the history
  • Loading branch information
blgm committed May 4, 2020
1 parent e6ca9a8 commit 2403b09
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
21 changes: 20 additions & 1 deletion marshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ type metakind uint

const (
metakindBasic metakind = iota
metakindStruct
metakindUnsupported
)

func Marshal(input interface{}) ([]byte, error) {
i := reflect.ValueOf(input)

// TODO: use actualMetakind() or similar
if i.Kind() == reflect.Ptr {
i = i.Elem()
}
Expand All @@ -35,7 +37,7 @@ func Marshal(input interface{}) ([]byte, error) {
func marshal(ctx context, in reflect.Value) (map[string]interface{}, error) {
out := make(map[string]interface{})

t := in.Type()
t := actualType(in)
for i := 0; i < t.NumField(); i++ {
v := in.Field(i)
f := t.Field(i)
Expand All @@ -44,6 +46,12 @@ func marshal(ctx context, in reflect.Value) (map[string]interface{}, error) {
switch actualMetakind(v) {
case metakindBasic:
out[f.Name] = v.Interface()
case metakindStruct:
r, err := marshal(ctx, actualValue(v))
if err != nil {
return nil, err
}
out[f.Name] = r
default:
return nil, NewUnsupportedTypeError(ctx, actualType(v))
}
Expand All @@ -56,6 +64,8 @@ func actualMetakind(v reflect.Value) metakind {
switch v.Kind() {
case reflect.Interface:
return actualMetakind(v.Elem())
case reflect.Struct:
return metakindStruct
case reflect.String, reflect.Bool,
reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
Expand All @@ -74,3 +84,12 @@ func actualType(v reflect.Value) reflect.Type {
return v.Type()
}
}

func actualValue(v reflect.Value) reflect.Value {
switch v.Kind() {
case reflect.Interface:
return v.Elem()
default:
return v
}
}
1 change: 1 addition & 0 deletions marshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var _ = Describe("Marshal", func() {
Entry("boolean", c{V: true}, `{"V":true}`),
Entry("int", c{V: 42}, `{"V":42}`),
Entry("float", c{V: 4.2}, `{"V":4.2}`),
Entry("struct", c{V: c{V: "hierarchical"}}, `{"V":{"V":"hierarchical"}}`),
)

DescribeTable(
Expand Down

0 comments on commit 2403b09

Please sign in to comment.