Allow skipping invalid fields when marshalling (#2967)

Currently unexported fields refuse to marshal or unmarshal, even if
they're told to skip. Now, they can be skipped. By default, they are
still errors.
This commit is contained in:
Ben Kalman
2016-12-20 16:47:49 -08:00
committed by GitHub
parent cb3390924f
commit 4eca6085cb
4 changed files with 37 additions and 7 deletions

View File

@@ -254,13 +254,13 @@ func structDecoder(t reflect.Type) decoderFunc {
fields := make([]decField, 0, t.NumField())
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
validateField(f, t)
tags := getTags(f)
if tags.skip {
continue
}
validateField(f, t)
fields = append(fields, decField{
name: tags.name,
decoder: typeDecoder(f.Type, tags),

View File

@@ -813,3 +813,18 @@ func TestDecodeOriginalReceiveTypeError(t *testing.T) {
assert.Error(err)
assert.Equal(`Cannot unmarshal struct S {} into Go value of type marshal.S, field with tag "original" must have type Struct`, err.Error())
}
func TestDecodeCanSkipUnexportedField(t *testing.T) {
assert := assert.New(t)
type S struct {
Abc int
notExported bool `noms:"-"`
}
var s S
err := Unmarshal(types.NewStruct("S", types.StructData{
"abc": types.Number(42),
}), &s)
assert.NoError(err)
assert.Equal(S{42, false}, s)
}

View File

@@ -356,17 +356,17 @@ func typeFields(t reflect.Type, parentStructTypes []reflect.Type) (fields fieldS
canComputeStructType := true
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
tags := getTags(f)
if tags.skip {
continue
}
validateField(f, t)
nt := nomsType(f.Type, parentStructTypes)
if nt == nil {
canComputeStructType = false
}
tags := getTags(f)
if tags.skip {
continue
}
if tags.omitEmpty {
canComputeStructType = false
}

View File

@@ -632,6 +632,21 @@ func TestInvalidTag(t *testing.T) {
assert.Equal(t, `Unrecognized tag: omitEmpty`, err.Error())
}
func TestEncodeCanSkipUnexportedField(t *testing.T) {
assert := assert.New(t)
type S struct {
Abc int
notExported bool `noms:"-"`
}
s := S{42, true}
v, err := Marshal(s)
assert.NoError(err)
assert.True(types.NewStruct("S", types.StructData{
"abc": types.Number(42),
}).Equals(v))
}
type TestInterface interface {
M()
}