From d9b91727b9a4323a66ebadfccc11d4ce0344ac4d Mon Sep 17 00:00:00 2001 From: Caleb Spare Date: Tue, 30 May 2023 08:10:12 -0700 Subject: [PATCH] Evaluate omitempty against un-dereferenced fields (#392) Fixes #371 --- encode.go | 23 ++++++++++++++--------- encode_test.go | 3 --- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/encode.go b/encode.go index 9bf80ecb..15a0ec39 100644 --- a/encode.go +++ b/encode.go @@ -493,24 +493,27 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value, inline bool) { writeFields := func(fields [][]int) { for _, fieldIndex := range fields { fieldType := rt.FieldByIndex(fieldIndex) - fieldVal := eindirect(rv.FieldByIndex(fieldIndex)) + fieldVal := rv.FieldByIndex(fieldIndex) - if isNil(fieldVal) { /// Don't write anything for nil fields. + opts := getOptions(fieldType.Tag) + if opts.skip { + continue + } + if opts.omitempty && isEmpty(fieldVal) { continue } - opts := getOptions(fieldType.Tag) - if opts.skip { + fieldVal = eindirect(fieldVal) + + if isNil(fieldVal) { // Don't write anything for nil fields. continue } + keyName := fieldType.Name if opts.name != "" { keyName = opts.name } - if opts.omitempty && enc.isEmpty(fieldVal) { - continue - } if opts.omitzero && isZero(fieldVal) { continue } @@ -652,7 +655,7 @@ func isZero(rv reflect.Value) bool { return false } -func (enc *Encoder) isEmpty(rv reflect.Value) bool { +func isEmpty(rv reflect.Value) bool { switch rv.Kind() { case reflect.Array, reflect.Slice, reflect.Map, reflect.String: return rv.Len() == 0 @@ -667,13 +670,15 @@ func (enc *Encoder) isEmpty(rv reflect.Value) bool { // type b struct{ s []string } // s := a{field: b{s: []string{"AAA"}}} for i := 0; i < rv.NumField(); i++ { - if !enc.isEmpty(rv.Field(i)) { + if !isEmpty(rv.Field(i)) { return false } } return true case reflect.Bool: return !rv.Bool() + case reflect.Ptr: + return rv.IsNil() } return false } diff --git a/encode_test.go b/encode_test.go index f1390c6c..53e59013 100644 --- a/encode_test.go +++ b/encode_test.go @@ -261,8 +261,6 @@ func TestEncodeOmitEmptyPointer(t *testing.T) { }) t.Run("zero values", func(t *testing.T) { - // TODO: this needs to be fixed; https://github.com/BurntSushi/toml/issues/371 - t.Skip() str := "" sl := []string{} m := map[string]string{} @@ -277,7 +275,6 @@ func TestEncodeOmitEmptyPointer(t *testing.T) { slice = [] [map] - XXX = "" [struct] string = ""