Skip to content

Commit

Permalink
fix: remove omitempty in common/json (#251)
Browse files Browse the repository at this point in the history
so we can add omitempty tag in models.go while keeping code compatible
  • Loading branch information
sesky4 authored Feb 27, 2024
1 parent 1e297ce commit dea6002
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 132 deletions.
27 changes: 11 additions & 16 deletions tencentcloud/common/json/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,9 +640,6 @@ func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
first := true
for i, f := range se.fields {
fv := fieldByIndex(v, f.index)
if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
continue
}
if !fv.IsValid() || f.omitNil && isNilValue(fv) {
continue
}
Expand Down Expand Up @@ -1046,12 +1043,11 @@ type field struct {
nameBytes []byte // []byte(name)
equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent

tag bool
index []int
typ reflect.Type
omitEmpty bool
omitNil bool
quoted bool
tag bool
index []int
typ reflect.Type
omitNil bool
quoted bool
}

func fillField(f field) field {
Expand Down Expand Up @@ -1164,13 +1160,12 @@ func typeFields(t reflect.Type) []field {
name = sf.Name
}
fields = append(fields, fillField(field{
name: name,
tag: tagged,
index: index,
typ: ft,
omitEmpty: opts.Contains("omitempty"),
omitNil: opts.Contains("omitnil"),
quoted: quoted,
name: name,
tag: tagged,
index: index,
typ: ft,
omitNil: opts.Contains("omitnil"),
quoted: quoted,
}))
if count[f.typ] > 1 {
// If there were multiple instances, add a second,
Expand Down
116 changes: 0 additions & 116 deletions tencentcloud/common/json/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,6 @@ var optionalsExpected = `{
"sto": {}
}`

func TestOmitEmpty(t *testing.T) {
var o Optionals
o.Sw = "something"
o.Mr = map[string]interface{}{}
o.Mo = map[string]interface{}{}

got, err := MarshalIndent(&o, "", " ")
if err != nil {
t.Fatal(err)
}
if got := string(got); got != optionalsExpected {
t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
}
}

type StringTag struct {
BoolStr bool `json:",string"`
IntStr int64 `json:",string"`
Expand Down Expand Up @@ -881,107 +866,6 @@ func TestMarshalFloat(t *testing.T) {
test(math.Copysign(0, -1), 32)
}

func TestMarshalRawMessageValue(t *testing.T) {
type (
T1 struct {
M RawMessage `json:",omitempty"`
}
T2 struct {
M *RawMessage `json:",omitempty"`
}
)

var (
rawNil = RawMessage(nil)
rawEmpty = RawMessage([]byte{})
rawText = RawMessage([]byte(`"foo"`))
)

tests := []struct {
in interface{}
want string
ok bool
}{
// Test with nil RawMessage.
{rawNil, "null", true},
{&rawNil, "null", true},
{[]interface{}{rawNil}, "[null]", true},
{&[]interface{}{rawNil}, "[null]", true},
{[]interface{}{&rawNil}, "[null]", true},
{&[]interface{}{&rawNil}, "[null]", true},
{struct{ M RawMessage }{rawNil}, `{"M":null}`, true},
{&struct{ M RawMessage }{rawNil}, `{"M":null}`, true},
{struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true},
{&struct{ M *RawMessage }{&rawNil}, `{"M":null}`, true},
{map[string]interface{}{"M": rawNil}, `{"M":null}`, true},
{&map[string]interface{}{"M": rawNil}, `{"M":null}`, true},
{map[string]interface{}{"M": &rawNil}, `{"M":null}`, true},
{&map[string]interface{}{"M": &rawNil}, `{"M":null}`, true},
{T1{rawNil}, "{}", true},
{T2{&rawNil}, `{"M":null}`, true},
{&T1{rawNil}, "{}", true},
{&T2{&rawNil}, `{"M":null}`, true},

// Test with empty, but non-nil, RawMessage.
{rawEmpty, "", false},
{&rawEmpty, "", false},
{[]interface{}{rawEmpty}, "", false},
{&[]interface{}{rawEmpty}, "", false},
{[]interface{}{&rawEmpty}, "", false},
{&[]interface{}{&rawEmpty}, "", false},
{struct{ X RawMessage }{rawEmpty}, "", false},
{&struct{ X RawMessage }{rawEmpty}, "", false},
{struct{ X *RawMessage }{&rawEmpty}, "", false},
{&struct{ X *RawMessage }{&rawEmpty}, "", false},
{map[string]interface{}{"nil": rawEmpty}, "", false},
{&map[string]interface{}{"nil": rawEmpty}, "", false},
{map[string]interface{}{"nil": &rawEmpty}, "", false},
{&map[string]interface{}{"nil": &rawEmpty}, "", false},
{T1{rawEmpty}, "{}", true},
{T2{&rawEmpty}, "", false},
{&T1{rawEmpty}, "{}", true},
{&T2{&rawEmpty}, "", false},

// Test with RawMessage with some text.
//
// The tests below marked with Issue6458 used to generate "ImZvbyI=" instead "foo".
// This behavior was intentionally changed in Go 1.8.
// See https://golang.org/issues/14493#issuecomment-255857318
{rawText, `"foo"`, true}, // Issue6458
{&rawText, `"foo"`, true},
{[]interface{}{rawText}, `["foo"]`, true}, // Issue6458
{&[]interface{}{rawText}, `["foo"]`, true}, // Issue6458
{[]interface{}{&rawText}, `["foo"]`, true},
{&[]interface{}{&rawText}, `["foo"]`, true},
{struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true}, // Issue6458
{&struct{ M RawMessage }{rawText}, `{"M":"foo"}`, true},
{struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true},
{&struct{ M *RawMessage }{&rawText}, `{"M":"foo"}`, true},
{map[string]interface{}{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458
{&map[string]interface{}{"M": rawText}, `{"M":"foo"}`, true}, // Issue6458
{map[string]interface{}{"M": &rawText}, `{"M":"foo"}`, true},
{&map[string]interface{}{"M": &rawText}, `{"M":"foo"}`, true},
{T1{rawText}, `{"M":"foo"}`, true}, // Issue6458
{T2{&rawText}, `{"M":"foo"}`, true},
{&T1{rawText}, `{"M":"foo"}`, true},
{&T2{&rawText}, `{"M":"foo"}`, true},
}

for i, tt := range tests {
b, err := Marshal(tt.in)
if ok := (err == nil); ok != tt.ok {
if err != nil {
t.Errorf("test %d, unexpected failure: %v", i, err)
} else {
t.Errorf("test %d, unexpected success", i)
}
}
if got := string(b); got != tt.want {
t.Errorf("test %d, Marshal(%#v) = %q, want %q", i, tt.in, got, tt.want)
}
}
}

type marshalPanic struct{}

func (marshalPanic) MarshalJSON() ([]byte, error) { panic(0xdead) }
Expand Down

0 comments on commit dea6002

Please # to comment.