Skip to content

Commit

Permalink
Merge pull request #81 from bbuck/omitempty
Browse files Browse the repository at this point in the history
Support for omitempty, as well as tests for omitempty.
  • Loading branch information
BurntSushi committed May 1, 2015
2 parents 443a628 + aa708eb commit 056c9bc
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
55 changes: 55 additions & 0 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value) {
if keyName == "" {
keyName = sft.Name
}

keyName, opts := getOptions(keyName)
if _, ok := opts["omitempty"]; ok && isEmpty(sf) {
continue
} else if _, ok := opts["omitzero"]; ok && isZero(sf) {
continue
}

enc.encode(key.add(keyName), sf)
}
}
Expand Down Expand Up @@ -433,6 +441,53 @@ func tomlArrayType(rv reflect.Value) tomlType {
return firstType
}

func getOptions(keyName string) (string, map[string]struct{}) {
opts := make(map[string]struct{})
ss := strings.Split(keyName, ",")
name := ss[0]
if len(ss) > 1 {
for _, opt := range ss {
opts[opt] = struct{}{}
}
}

return name, opts
}

func isZero(rv reflect.Value) bool {
switch rv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
if rv.Int() == 0 {
return true
}
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
if rv.Uint() == 0 {
return true
}
case reflect.Float32, reflect.Float64:
if rv.Float() == 0.0 {
return true
}
}

return false
}

func isEmpty(rv reflect.Value) bool {
switch rv.Kind() {
case reflect.String:
if len(strings.TrimSpace(rv.String())) == 0 {
return true
}
case reflect.Array, reflect.Slice, reflect.Map:
if rv.Len() == 0 {
return true
}
}

return false
}

func (enc *Encoder) newline() {
if enc.hasWritten {
enc.wf("\n")
Expand Down
36 changes: 36 additions & 0 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,42 @@ func TestEncodeArrayHashWithNormalHashOrder(t *testing.T) {
encodeExpected(t, "array hash with normal hash order", val, expected, nil)
}

func TestEncodeWithOmitEmpty(t *testing.T) {
type simple struct {
User string `toml:"user"`
Pass string `toml:"password,omitempty"`
}

value := simple{"Testing", ""}
expected := fmt.Sprintf("user = %q\n", value.User)
encodeExpected(t, "simple with omitempty, is empty", value, expected, nil)
value.Pass = "some password"
expected = fmt.Sprintf("user = %q\npassword = %q\n", value.User, value.Pass)
encodeExpected(t, "simple with omitempty, not empty", value, expected, nil)
}

func TestEncodeWithOmitZero(t *testing.T) {
type simple struct {
Number int `toml:"number,omitzero"`
Real float64 `toml:"real,omitzero"`
Unsigned uint `toml:"unsigned,omitzero"`
}

value := simple{0, 0.0, uint(0)}
expected := ""

encodeExpected(t, "simple with omitzero, all zero", value, expected, nil)

value.Number = 10
value.Real = 20
value.Unsigned = 5
expected = `number = 10
real = 20.0
unsigned = 5
`
encodeExpected(t, "simple with omitzero, non-zero", value, expected, nil)
}

func encodeExpected(
t *testing.T, label string, val interface{}, wantStr string, wantErr error,
) {
Expand Down

0 comments on commit 056c9bc

Please sign in to comment.