Closed a-watters closed 3 years ago
This is a known issue with how the 6.x version of gogen-avro generates structs to store maps. The 7.x releases fixed this issue and should encode a map to JSON as expected. JSON encoding support is an ongoing effort, and my goal is to have 8.x be fully compliant with the Avro spec. Let me know if you have any issues with the 7.x or 8.x beta release!
I'm seeing this issue using v7.3.0
someFooMap := avro.NewMapString()
someFoo := avro.Foo{FooMap: someFooMap}
jsonFoo, _ := json.Marshal(someFoo)
Can you post the generated code for the map type?
`// Code generated by github.com/actgardner/gogen-avro. DO NOT EDIT. /*
package foo
import ( "github.com/actgardner/gogen-avro/vm" "github.com/actgardner/gogen-avro/vm/types" "io" )
func writeMapString(r *MapString, w io.Writer) error { err := vm.WriteLong(int64(len(r.M)), w) if err != nil || len(r.M) == 0 { return err } for k, e := range r.M { err = vm.WriteString(k, w) if err != nil { return err } err = vm.WriteString(e, w) if err != nil { return err } } return vm.WriteLong(0, w) }
type MapString struct { keys []string values []string M map[string]string }
func NewMapString() *MapString { return &MapString{ keys: make([]string, 0), values: make([]string, 0), M: make(map[string]string), } }
func ( *MapString) SetBoolean(v bool) { panic("Unsupported operation") } func ( MapString) SetInt(v int32) { panic("Unsupported operation") } func (_ MapString) SetLong(v int64) { panic("Unsupported operation") } func ( *MapString) SetFloat(v float32) { panic("Unsupported operation") } func ( MapString) SetDouble(v float64) { panic("Unsupported operation") } func (_ MapString) SetBytes(v []byte) { panic("Unsupported operation") } func ( *MapString) SetString(v string) { panic("Unsupported operation") } func ( MapString) SetUnionElem(v int64) { panic("Unsupported operation") } func (_ MapString) Get(i int) types.Field { panic("Unsupported operation") } func (_ MapString) SetDefault(i int) { panic("Unsupported operation") } func (r MapString) Finalize() { for i := range r.keys { r.M[r.keys[i]] = r.values[i] } r.keys = nil r.values = nil }
func (r *MapString) AppendMap(key string) types.Field { r.keys = append(r.keys, key) var v string
r.values = append(r.values, v)
return (*types.String)(&r.values[len(r.values)-1])
}
func (_ *MapString) AppendArray() types.Field { panic("Unsupported operation") } `
That doesn't look like code generated with v7, the imports and comment should be github.com/actgardner/gogen-avro/v7
. Can you remove and reinstall the gogen-avro binary and regenerate the code?
Having defined a struct foo which contains a map fooMap the resulting json.Marshal adds an additional 'M' level to the json.
avsc file: { "namespace": "example.foo", "type": "record", "name": "foo", "fields": [ { "name": "fooMap", "type": { "type": "map", "values": "string" }, "golang.tags": "json:\"fooMap\"" } ] }
output json:
{"fooMap":{"M":{"key":"value"}}}