naoina / toml

TOML parser and encoder library for Golang
MIT License
294 stars 50 forks source link

Support encoding maps / disambiguate nested structs and basic values #17

Closed timraymond closed 7 years ago

timraymond commented 8 years ago

This add support for encoding maps. It makes the assumption that map keys are either strings or fmt.Stringers. Keys are sorted prior to encoding to ensure consistent ordering.

As part of this, I ran into issues where a map or struct nested within the struct I was trying to marshal would have its values confused with values found in the parent struct (see #12). Basically this contrived example:

type User struct {
  Preferences map[string]string
  Name string
}

tim := User{
  "Tim",
  map[string]string{
    "ice_cream": "vanilla",
  }
}

out, err := toml.Marshal(tim)

Would produce TOML that looks something like this:

[user]
[user.Preferences]
ice_cream="vanilla"
name="Tim"

When the "name" key-value pair belongs under [user]. This patch writes simple values and nested structs / maps / slices to separate buffers in marshal and then writes them back in an unambiguous order (basic values first, then nested objects).

Fixes #11 Fixes #12

fjl commented 7 years ago

All features of this PR are implemented in 7a7dfc266325a3c3d7b10772173101ffcb7b73a9. I chose to do it slightly differently to support the implementation of MarshalerRec.