alvaroloes / enumer

A Go tool to auto generate methods for your enums
Other
478 stars 111 forks source link

enumer does not convert enum keys of map to strings on JSON Marshal #27

Closed mithmatt closed 6 years ago

mithmatt commented 6 years ago

Eg (pseudocode):

enums/myenum.go:

//go:generate enumer -type=MyEnum -json -sql

// MyEnum:
type MyEnum int

const (
  MyEnumA MyEnum = iota + 1
  MyEnumB
  MyEnumC
)

main.go:


func main() {
  myMap := make(map[enums.MyEnum]string)
  myMap[enums.MyEnumA] = "A"
  myMap[enums.MyEnumB] = "B"

  jsonBytes, _ := json.MarshalIndent(HostRecommendationConfig,"", "  ")
  fmt.Println(string(jsonBytes))
}

The above code will print the output:

{
  "1": "A",
  "2": "B"
}

Expected output:

{
  "A": "A",
  "B": "B"
}
alvaroloes commented 6 years ago

Hi @mithmatt. Thank you for raising the issue. This is because map keys are handled differently when they are marshaled to JSON. As per the documentation (https://golang.org/pkg/encoding/json/#Marshal)

Map values encode as JSON objects. The map's key type must either be a string, an integer type, or implement encoding.TextMarshaler. The map keys are sorted and used as JSON object keys by applying the following rules, subject to the UTF-8 coercion described for string values above:

  • string keys are used directly
  • encoding.TextMarshalers are marshaled
  • integer keys are converted to strings

So in order for map keys to work properly, the type must implement the encoding.TextMarshaler interface. I'll add this feature under the new flag name text

alvaroloes commented 6 years ago

Done! @mithmatt check the latest changes. You need to include the new flag text (besides json) and your map keys will be properly encoded ;-)

mithmatt commented 6 years ago

@alvaroloes Thanks. I see the new commit that you added.