linkedin / goavro

Apache License 2.0
972 stars 216 forks source link

Cannot encode enum #71

Closed StarpTech closed 7 years ago

StarpTech commented 7 years ago
package main

import (
    "bytes"
    "log"

    "github.com/linkedin/goavro"
)

func main() {

    recordSchemaJSON := `{
            "name": "Request",
            "type": "record",
            "fields": [{
                "name": "type",
                "type": "enum",
                "symbols": ["request", "pubsub"],
                "default": "request"
            }]
        }`

    codec, err := goavro.NewCodec(recordSchemaJSON)
    if err != nil {
        log.Fatal(err)
    }

    record, err := goavro.NewRecord(goavro.RecordSchema(recordSchemaJSON))
    if err != nil {
        log.Fatal(err)
    }

    record.Set("type", "request")

    bb := new(bytes.Buffer)
    if err = codec.Encode(bb, record); err != nil {
        log.Fatal(err)
    }

}
E:\Repositorys\hemera-golang>go run main.go
2017/01/27 23:35:19 cannot encode record (Request): cannot encode enum (type): expected: Enum; received: string
exit status 1
karrick commented 7 years ago

@StarpTech, this is definitely a bug. In the past Enum values were encoded from strings. The encoder would lookup the provided string in the list of permitted string values for the enum, and if the value did not match one in the list, it would cause the error.

There was a change quite a while ago that compelled a change to require enum values to be given to the encoder as a goavro.Enum type. While I don't remember why right now why this change was required, it does make the API a little awkward.

I know if you pass an goavro.Enum object to the encoder, it does work. That's what we're using around here. If I can, I'll try to see about making the more obvious behavior come back however.

StarpTech commented 7 years ago

Hi @karrick why did you closed this issue?

StarpTech commented 7 years ago

@karrick I didnt see the commit on mobile thanks! Could you also add a test?

karrick commented 7 years ago

@StarpTech, sorry about that. What I saw as a quick fix without a proper test case wasn't really a fix. Re-opening this issue and looking at it more.

It turns out this issue is a bit more complex than I initially realized. Thanks for bringing it to my attention.

StarpTech commented 7 years ago

Hi @karrick any updates?

karrick commented 7 years ago

@StarpTech,

The new version of the library at https://github.com/karrick/goavro can handle enums well enough with a lot less hand-holding.

`package main

import ( "fmt" "log"

"github.com/karrick/goavro"

)

func main() {

recordSchemaJSON := `{
        "name": "Request",
        "type": "record",
        "fields": [{
            "name": "type",
            "type": "enum",
            "symbols": ["request", "pubsub"],
            "default": "request"
        }]
    }`

codec, err := goavro.NewCodec(recordSchemaJSON)
if err != nil {
    log.Fatal(err)
}

buf, err := codec.TextualFromNative(nil, map[string]interface{}{"type": "request"})
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(buf))
// Output: {"type":"request"}

} `

I'm closing this issue as "Won't Fix" because it's been fixed in the next version.