datastore: fix handling of embedded unexported structs (#58)

This commit is contained in:
Kaur Kuut 2017-03-08 01:55:54 +02:00 коммит произвёл Adam Tanner
Родитель 5403c08c6e
Коммит b79c28f019
2 изменённых файлов: 14 добавлений и 8 удалений

Просмотреть файл

@ -199,8 +199,8 @@ func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) {
f := t.Field(i)
// Skip unexported fields.
// Note that if f is an anonymous, unexported struct field,
// we will not promote its fields. We will skip f entirely.
if f.PkgPath != "" {
// we will promote its fields.
if f.PkgPath != "" && !f.Anonymous {
continue
}
@ -253,11 +253,13 @@ func getStructCodecLocked(t reflect.Type) (ret *structCodec, retErr error) {
"datastore: flattening nested structs leads to a slice of slices: field %q", f.Name)
}
c.hasSlice = c.hasSlice || sub.hasSlice
// If name is empty at this point, f is an anonymous struct field.
// In this case, we promote the substruct's fields up to this level
// If f is an anonymous struct field, we promote the substruct's fields up to this level
// in the linked list of struct codecs.
if name == "" {
if f.Anonymous {
for subname, subfield := range sub.fields {
if name != "" {
subname = name + "." + subname
}
if _, ok := c.fields[subname]; ok {
return nil, fmt.Errorf("datastore: struct tag has repeated property name: %q", subname)
}

Просмотреть файл

@ -97,6 +97,7 @@ func TestStructCodec(t *testing.T) {
"R": {path: []int{0}},
"S": {path: []int{1}, structCodec: pStructCodec},
"T": {path: []int{2}, structCodec: oStructCodec},
"O": {path: []int{3, 0}},
},
complete: true,
}
@ -209,6 +210,7 @@ func TestStructCodec(t *testing.T) {
"B": {path: []int{1}},
"CC": {path: []int{2}, structCodec: oStructCodec},
"DDD": {path: []int{3}, structCodec: rStructCodec},
"O": {path: []int{4, 0}},
},
complete: true,
},
@ -224,9 +226,10 @@ func TestStructCodec(t *testing.T) {
}{},
&structCodec{
fields: map[string]fieldCodec{
"w": {path: []int{1}},
"xx": {path: []int{2}, structCodec: oStructCodec},
"y": {path: []int{3}, structCodec: rStructCodec},
"w": {path: []int{1}},
"xx": {path: []int{2}, structCodec: oStructCodec},
"y": {path: []int{3}, structCodec: rStructCodec},
"z.O": {path: []int{4, 0}},
},
complete: true,
},
@ -244,6 +247,7 @@ func TestStructCodec(t *testing.T) {
fields: map[string]fieldCodec{
"B": {path: []int{1}},
"D": {path: []int{3}, structCodec: uStructCodec},
"U": {path: []int{4, 0}},
},
complete: true,
},