package main import ( "fmt" "io" messages "git.tornberg.me/go-cart-actor/proto" "google.golang.org/protobuf/proto" ) var Handlers = map[uint16]MessageHandler{ AddRequestType: &AddRequestHandler{}, AddItemType: &AddItemHandler{}, ChangeQuantityType: &ChangeQuantityHandler{}, SetDeliveryType: &SetDeliveryHandler{}, RemoveItemType: &RemoveItemHandler{}, RemoveDeliveryType: &RemoveDeliveryHandler{}, } func GetMessageHandler(t uint16) (MessageHandler, error) { h, ok := Handlers[t] if !ok { return nil, fmt.Errorf("no handler for type %d", t) } return h, nil } type MessageHandler interface { Write(*Message, io.Writer) error Read(data []byte) (interface{}, error) Is(*Message) bool } type TypedMessageHandler struct { Type uint16 } type AddRequestHandler struct { TypedMessageHandler } func (h *AddRequestHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.AddRequest)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *AddRequestHandler) Read(data []byte) (interface{}, error) { msg := &messages.AddRequest{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *AddRequestHandler) Is(m *Message) bool { if m.Type != AddRequestType { return false } _, ok := m.Content.(*messages.AddRequest) return ok } type AddItemHandler struct { TypedMessageHandler } func (h *AddItemHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.AddItem)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *AddItemHandler) Read(data []byte) (interface{}, error) { msg := &messages.AddItem{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *AddItemHandler) Is(m *Message) bool { if m.Type != AddItemType { return false } _, ok := m.Content.(*messages.AddItem) return ok } type ChangeQuantityHandler struct { TypedMessageHandler } func (h *ChangeQuantityHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.ChangeQuantity)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *ChangeQuantityHandler) Read(data []byte) (interface{}, error) { msg := &messages.ChangeQuantity{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *ChangeQuantityHandler) Is(m *Message) bool { if m.Type != ChangeQuantityType { return false } _, ok := m.Content.(*messages.ChangeQuantity) return ok } type SetDeliveryHandler struct { TypedMessageHandler } func (h *SetDeliveryHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.SetDelivery)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *SetDeliveryHandler) Read(data []byte) (interface{}, error) { msg := &messages.SetDelivery{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *SetDeliveryHandler) Is(m *Message) bool { if m.Type != ChangeQuantityType { return false } _, ok := m.Content.(*messages.SetDelivery) return ok } type RemoveItemHandler struct { TypedMessageHandler } func (h *RemoveItemHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.RemoveItem)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *RemoveItemHandler) Read(data []byte) (interface{}, error) { msg := &messages.RemoveItem{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *RemoveItemHandler) Is(m *Message) bool { if m.Type != AddItemType { return false } _, ok := m.Content.(*messages.RemoveItem) return ok } type RemoveDeliveryHandler struct { TypedMessageHandler } func (h *RemoveDeliveryHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.RemoveDelivery)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *RemoveDeliveryHandler) Read(data []byte) (interface{}, error) { msg := &messages.RemoveDelivery{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *RemoveDeliveryHandler) Is(m *Message) bool { if m.Type != AddItemType { return false } _, ok := m.Content.(*messages.RemoveDelivery) return ok } type CheckoutHandler struct { TypedMessageHandler } func (h *CheckoutHandler) Write(m *Message, w io.Writer) error { messageBytes, err := proto.Marshal(m.Content.(*messages.CreateCheckoutOrder)) if err != nil { return err } w.Write(messageBytes) return nil } func (h *CheckoutHandler) Read(data []byte) (interface{}, error) { msg := &messages.CreateCheckoutOrder{} err := proto.Unmarshal(data, msg) if err != nil { return nil, err } return msg, nil } func (h *CheckoutHandler) Is(m *Message) bool { if m.Type != CreateCheckoutOrderType { return false } _, ok := m.Content.(*messages.CreateCheckoutOrder) return ok }