Skip to content

Commit 360c9e3

Browse files
committed
Don't return error on uncomparable types: just silently ignore like before
This is more compatible with the previous behaviour, as well as what stdlib does. Ref: #360
1 parent 929b0a7 commit 360c9e3

File tree

2 files changed

+30
-48
lines changed

2 files changed

+30
-48
lines changed

encode.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -654,10 +654,9 @@ func (enc *Encoder) isEmpty(rv reflect.Value) bool {
654654
case reflect.Array, reflect.Slice, reflect.Map, reflect.String:
655655
return rv.Len() == 0
656656
case reflect.Struct:
657-
if !rv.Type().Comparable() {
658-
encPanic(fmt.Errorf("type %q cannot be used with omitempty as it's uncomparable", rv.Type()))
657+
if rv.Type().Comparable() {
658+
return reflect.Zero(rv.Type()).Interface() == rv.Interface()
659659
}
660-
return reflect.Zero(rv.Type()).Interface() == rv.Interface()
661660
case reflect.Bool:
662661
return !rv.Bool()
663662
}

encode_test.go

+28-45
Original file line numberDiff line numberDiff line change
@@ -182,23 +182,33 @@ func TestEncodeOmitEmptyStruct(t *testing.T) {
182182
}
183183

184184
func TestEncodeWithOmitEmpty(t *testing.T) {
185+
type uncomparable struct {
186+
Field []string `toml:"Field,omitempty"`
187+
}
185188
type simple struct {
186-
Bool bool `toml:"bool,omitempty"`
187-
String string `toml:"string,omitempty"`
188-
Array [0]byte `toml:"array,omitempty"`
189-
Slice []int `toml:"slice,omitempty"`
190-
Map map[string]string `toml:"map,omitempty"`
191-
Time time.Time `toml:"time,omitempty"`
189+
Bool bool `toml:"bool,omitempty"`
190+
String string `toml:"string,omitempty"`
191+
Array [0]byte `toml:"array,omitempty"`
192+
Slice []int `toml:"slice,omitempty"`
193+
Map map[string]string `toml:"map,omitempty"`
194+
Time time.Time `toml:"time,omitempty"`
195+
Uncomparable1 uncomparable `toml:"uncomparable1,omitempty"`
196+
Uncomparable2 uncomparable `toml:"uncomparable2,omitempty"`
192197
}
193198

194199
var v simple
195-
encodeExpected(t, "fields with omitempty are omitted when empty", v, "", nil)
200+
encodeExpected(t, "fields with omitempty are omitted when empty", v, `
201+
[uncomparable1]
202+
203+
[uncomparable2]
204+
`, nil)
196205
v = simple{
197-
Bool: true,
198-
String: " ",
199-
Slice: []int{2, 3, 4},
200-
Map: map[string]string{"foo": "bar"},
201-
Time: time.Date(1985, 6, 18, 15, 16, 17, 0, time.UTC),
206+
Bool: true,
207+
String: " ",
208+
Slice: []int{2, 3, 4},
209+
Map: map[string]string{"foo": "bar"},
210+
Time: time.Date(1985, 6, 18, 15, 16, 17, 0, time.UTC),
211+
Uncomparable2: uncomparable{[]string{"XXX"}},
202212
}
203213
expected := `bool = true
204214
string = " "
@@ -207,43 +217,16 @@ time = 1985-06-18T15:16:17Z
207217
208218
[map]
209219
foo = "bar"
220+
221+
[uncomparable1]
222+
223+
[uncomparable2]
224+
Field = ["XXX"]
210225
`
211226
encodeExpected(t, "fields with omitempty are not omitted when non-empty",
212227
v, expected, nil)
213228
}
214229

215-
func TestEncodeWithOmitEmptyError(t *testing.T) {
216-
type nest struct {
217-
Field []string `toml:"Field,omitempty"`
218-
}
219-
220-
tests := []struct {
221-
in interface{}
222-
wantErr string
223-
}{
224-
{ // Make sure it doesn't panic on uncomparable types; #360
225-
struct {
226-
Values nest `toml:"values,omitempty"`
227-
Empty nest `toml:"empty,omitempty"`
228-
}{Values: nest{[]string{"XXX"}}},
229-
"cannot be used with omitempty as it's uncomparable",
230-
},
231-
}
232-
233-
for _, tt := range tests {
234-
t.Run("", func(t *testing.T) {
235-
buf := new(bytes.Buffer)
236-
err := NewEncoder(buf).Encode(tt.in)
237-
if !errorContains(err, tt.wantErr) {
238-
t.Fatalf("wrong error: %v", err)
239-
}
240-
if buf.String() != "" {
241-
t.Errorf("output not empty:\n%s", buf)
242-
}
243-
})
244-
}
245-
}
246-
247230
func TestEncodeWithOmitZero(t *testing.T) {
248231
type simple struct {
249232
Number int `toml:"number,omitzero"`
@@ -1164,8 +1147,8 @@ ArrayOfMixedSlices = [[1, 2], ["a", "b"]]
11641147

11651148
func encodeExpected(t *testing.T, label string, val interface{}, want string, wantErr error) {
11661149
t.Helper()
1167-
11681150
t.Run(label, func(t *testing.T) {
1151+
t.Helper()
11691152
var buf bytes.Buffer
11701153
err := NewEncoder(&buf).Encode(val)
11711154
if err != wantErr {

0 commit comments

Comments
 (0)