Consider the example below, it accepts a JSON message which is eventually unmarshalled into several possible types. How can I reduce or remove the boilerplate code associated with adding another event type.
package main
import (
"encoding/json"
"fmt"
)
const input = `
{
"type": "hello",
"event": {
"name": "Picard"
}
}
`
type EventEnvelope struct {
Type string
Event interface{}
}
type EventHello struct {
Name string
}
type EventHowdy struct {
Name string
}
type Display struct {
formal chan EventHello
western chan EventHowdy
}
func newDisplay() *Display {
return &Display{
formal: make(chan EventHello),
western: make(chan EventHowdy),
}
}
func (display *Display) run() {
for {
select {
case formal := <-display.formal:
fmt.Println("Hello", formal.Name)
case western := <-display.western:
fmt.Println("Howdy", western.Name)
}
}
}
func main() {
var event json.RawMessage
env := EventEnvelope{
Event: &event,
}
if err := json.Unmarshal([]byte(input), &env); err != nil {
fmt.Print(err)
}
display := newDisplay()
go display.run()
events(display, event, env.Type)
}
func events(display *Display, raw json.RawMessage, event string) {
switch event {
case "hello":
hello := EventHello{}
if err := json.Unmarshal(raw, &hello); err != nil {
fmt.Println(err)
} else {
display.formal <- hello
}
case "howdy":
howdy := EventHowdy{}
if err := json.Unmarshal(raw, &howdy); err != nil {
fmt.Println(err)
} else {
display.western <- howdy
}
default:
fmt.Println("No event handler")
}
}
After unmarshalling the EventEnvelope, the actual event is left as a RawMessage. The event RawMessage is then unmarshalled into a specific type. Can this be dynamic? Only if there were no errors should we send it to the channel.
hello := EventHello{}
if err := json.Unmarshal(raw, &hello); err != nil {
fmt.Println(err)
} else {
display.formal <- hello
}
Same code in the playground: https://play.golang.org/p/WPC8JAFyxgq
Aucun commentaire:
Enregistrer un commentaire