Skip to content

Commit

Permalink
Support encoding comments. Fixes BurntSushi#75
Browse files Browse the repository at this point in the history
This implements the suggestion in the referenced issue.
I wouldn't say this is a particularly nuanced way to support
encoding comments, but it was easy to implement and I wanted
to see if people would be receptive to it.
  • Loading branch information
echlebek committed Oct 6, 2015
1 parent 056c9bc commit e68f68f
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 5 deletions.
40 changes: 35 additions & 5 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) {
return nil
}

// wrapper for Encoder.encode that writes a comment out above the field.
// panics on error like encode.
func (enc *Encoder) encodeCommented(key Key, rv reflect.Value, comment string) {
format := "\n# %s\n"
if !enc.hasWritten {
format = "# %s\n"
}
if _, err := fmt.Fprintf(enc.w, format, comment); err != nil {
panic(err)
}
enc.encode(key, rv)
}

func (enc *Encoder) encode(key Key, rv reflect.Value) {
// Special case. Time needs to be in ISO8601 format.
// Special case. If we can marshal the type to text, then we used that.
Expand Down Expand Up @@ -328,6 +341,7 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value) {
addFields(rt, rv, nil)

var writeFields = func(fields [][]int) {
OUTER:
for _, fieldIndex := range fields {
sft := rt.FieldByIndex(fieldIndex)
sf := rv.FieldByIndex(fieldIndex)
Expand All @@ -345,13 +359,29 @@ func (enc *Encoder) eStruct(key Key, rv reflect.Value) {
}

keyName, opts := getOptions(keyName)
if _, ok := opts["omitempty"]; ok && isEmpty(sf) {
continue
} else if _, ok := opts["omitzero"]; ok && isZero(sf) {
continue
var comment string
for opt := range opts {
switch opt {
case "omitempty":
if isEmpty(sf) {
continue OUTER
}
case "omitzero":
if isZero(sf) {
continue OUTER
}
case keyName:
continue
default:
comment = opt
}
}

enc.encode(key.add(keyName), sf)
if comment != "" {
enc.encodeCommented(key.add(keyName), sf, comment)
} else {
enc.encode(key.add(keyName), sf)
}
}
}
writeFields(fieldsDirect)
Expand Down
19 changes: 19 additions & 0 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,25 @@ unsigned = 5
encodeExpected(t, "simple with omitzero, non-zero", value, expected, nil)
}

func TestEncodeWithComment(t *testing.T) {
type elephant struct {
Age int `toml:"age,Elephant age in years"`
TuskLen int `toml:"tusk_length,Tusk length in cm"`
NWrinkles int `toml:"num_wrinkles,"`
}

value := elephant{5, 62, 1000}

expected := `# Elephant age in years
age = 5
# Tusk length in cm
tusk_length = 62
num_wrinkles = 1000
`
encodeExpected(t, "simple with encodeComment", value, expected, nil)
}

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

0 comments on commit e68f68f

Please sign in to comment.