From 6bc82b03ddc49cdec74ec1be0a2a1a8e1c323adf Mon Sep 17 00:00:00 2001 From: Erik Arvidsson Date: Wed, 21 Dec 2016 19:14:59 -0800 Subject: [PATCH] Revert "Marshal: Be more lenient when unmarshal a struct (#2975)" (#2977) This reverts commit b64f1d5dc936935f79718fe6a1b75b9a6b1af89b. Reason: It is breaking samples/go/photo-index Reopens: #2971 --- go/marshal/decode.go | 25 ++++++++++++++++--------- go/marshal/decode_test.go | 6 ++---- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/go/marshal/decode.go b/go/marshal/decode.go index 79efdc05c6..0dccf3968e 100644 --- a/go/marshal/decode.go +++ b/go/marshal/decode.go @@ -20,7 +20,10 @@ import ( // // To unmarshal a Noms struct into a Go struct, Unmarshal matches incoming // object fields to the fields used by Marshal (either the struct field name or -// its tag). Unmarshal will only set exported fields of the struct. Go struct +// its tag). Unmarshal will only set exported fields of the struct. The name +// of the Go struct must match (ignoring case) the name of the Noms struct. All +// exported fields on the Go struct must be present in the Noms struct, unless +// the field on the Go struct is marked with the "omitempty" tag. Go struct // fields also support the "original" tag which causes the Go field to receive // the entire original unmarshaled Noms struct. // @@ -231,10 +234,11 @@ func (c *decoderCacheT) set(t reflect.Type, d decoderFunc) { } type decField struct { - name string - decoder decoderFunc - index int - original bool + name string + decoder decoderFunc + index int + omitEmpty bool + original bool } func structDecoder(t reflect.Type) decoderFunc { @@ -258,10 +262,11 @@ func structDecoder(t reflect.Type) decoderFunc { validateField(f, t) fields = append(fields, decField{ - name: tags.name, - decoder: typeDecoder(f.Type, tags), - index: i, - original: tags.original, + name: tags.name, + decoder: typeDecoder(f.Type, tags), + index: i, + omitEmpty: tags.omitEmpty, + original: tags.original, }) } @@ -283,6 +288,8 @@ func structDecoder(t reflect.Type) decoderFunc { fv, ok := s.MaybeGet(f.name) if ok { f.decoder(fv, sf) + } else if !f.omitEmpty { + panic(&UnmarshalTypeMismatchError{v, rv.Type(), ", missing field \"" + f.name + "\""}) } } } diff --git a/go/marshal/decode_test.go b/go/marshal/decode_test.go index 2101ecc9b9..6e108b52a4 100644 --- a/go/marshal/decode_test.go +++ b/go/marshal/decode_test.go @@ -309,11 +309,9 @@ func TestDecodeMissingField(t *testing.T) { B bool } var s S - Unmarshal(types.NewStruct("S", types.StructData{ + assertDecodeErrorMessage(t, types.NewStruct("S", types.StructData{ "a": types.Number(42), - }), &s) - assert.Equal(t, int32(42), s.A) - assert.False(t, s.B) + }), &s, "Cannot unmarshal struct S {\n a: Number,\n} into Go value of type marshal.S, missing field \"b\"") } func TestDecodeEmbeddedStruct(tt *testing.T) {