structure: add omitnested feature to Map

This commit is contained in:
Fatih Arslan 2014-08-07 21:23:01 +03:00
parent fc5199c8cc
commit 137635f5eb
3 changed files with 40 additions and 8 deletions

View File

@ -34,7 +34,12 @@ func Map(s interface{}) map[string]interface{} {
var finalVal interface{} var finalVal interface{}
if IsStruct(val.Interface()) { tagName, tagOpts := parseTag(field.Tag.Get(DefaultTagName))
if tagName != "" {
name = tagName
}
if IsStruct(val.Interface()) && !tagOpts.Has("omitnested") {
// look out for embedded structs, and convert them to a // look out for embedded structs, and convert them to a
// map[string]interface{} too // map[string]interface{} too
finalVal = Map(val.Interface()) finalVal = Map(val.Interface())
@ -42,12 +47,6 @@ func Map(s interface{}) map[string]interface{} {
finalVal = val.Interface() finalVal = val.Interface()
} }
// override if the user passed a structure tag value
// ignore if the user passed the "-" value
if tag := field.Tag.Get(DefaultTagName); tag != "" {
name = tag
}
out[name] = finalVal out[name] = finalVal
} }

View File

@ -3,6 +3,7 @@ package structure
import ( import (
"reflect" "reflect"
"testing" "testing"
"time"
) )
func TestMapNonStruct(t *testing.T) { func TestMapNonStruct(t *testing.T) {
@ -145,6 +146,37 @@ func TestMap_CustomTag(t *testing.T) {
} }
func TestMap_OmitNested(t *testing.T) {
type A struct {
Name string
Value string
Time time.Time `structure:",omitnested"`
}
a := A{Time: time.Now()}
type B struct {
Desc string
A A
}
b := &B{A: a}
m := Map(b)
in, ok := m["A"].(map[string]interface{})
if !ok {
t.Error("Map nested structs is not available in the map")
}
// should not happen
if _, ok := in["Time"].(map[string]interface{}); ok {
t.Error("Map nested struct should omit recursiving parsing of Time")
}
if _, ok := in["Time"].(time.Time); !ok {
t.Error("Map nested struct should stop parsing of Time at is current value")
}
}
func TestMap_Nested(t *testing.T) { func TestMap_Nested(t *testing.T) {
type A struct { type A struct {
Name string Name string

View File

@ -17,7 +17,8 @@ func (t tagOptions) Has(opt string) bool {
} }
// parseTag splits a struct field's tag into its name and a list of options // parseTag splits a struct field's tag into its name and a list of options
// which comes after a name // which comes after a name. A tag is in the form of: "name,option1,option2".
// The name can be neglectected.
func parseTag(tag string) (string, tagOptions) { func parseTag(tag string) (string, tagOptions) {
res := strings.Split(tag, ",") res := strings.Split(tag, ",")