diff --git a/src/state/lobby/event.go b/src/state/lobby/event.go new file mode 100644 index 0000000..b8519cc --- /dev/null +++ b/src/state/lobby/event.go @@ -0,0 +1,63 @@ +package lobby + +import ( + "encoding/json" + "fmt" +) + +type Event interface { + LobbyEvent() +} + +type PlayerJoin struct { + ID int +} + +func (PlayerJoin) LobbyEvent() {} + +type PlayerLeave struct { + ID int +} + +func (PlayerLeave) LobbyEvent() {} + +func ParseEvent(b []byte) (Event, error) { + var wrapper struct { + Type string `json:"type"` + Package string `json:"package"` + Payload json.RawMessage `json:"payload"` + } + if err := json.Unmarshal(b, &wrapper); err != nil { + return nil, err + } else if wrapper.Package != "lobby" { + return nil, nil + } + + var e Event + var err error + switch wrapper.Type { + case "lobby.PlayerJoin": + v := PlayerJoin{} + err = json.Unmarshal(wrapper.Payload, &v) + e = v + case "lobby.PlayerLeave": + v := PlayerLeave{} + err = json.Unmarshal(wrapper.Payload, &v) + e = v + default: + return nil, fmt.Errorf("failed to parse event %q", wrapper.Type) + } + return e, err +} + +func MarshalEvent(e Event) ([]byte, error) { + var marshalme struct { + Payload Event `json:"payload"` + Type string `json:"type"` + Package string `json:"package"` + } + marshalme.Payload = e + marshalme.Type = fmt.Sprintf("%T", e) + marshalme.Package = "lobby" + return json.Marshal(marshalme) +} diff --git a/src/state/lobby/event_test.go b/src/state/lobby/event_test.go new file mode 100644 index 0000000..3b5d8c5 --- /dev/null +++ b/src/state/lobby/event_test.go @@ -0,0 +1,36 @@ +package lobby_test + +import ( + "gitea/price-is-wrong/src/state/lobby" + "testing" +) + +func TestMarshalUnmarshal(t *testing.T) { + cases := map[string]struct { + e lobby.Event + }{ + "PlayerJoin": {e: lobby.PlayerJoin{ID: 1}}, + "PlayerLeave": {e: lobby.PlayerLeave{ID: 1}}, + } + + for name, d := range cases { + c := d + t.Run(name, func(t *testing.T) { + b, err := lobby.MarshalEvent(c.e) + if err != nil { + t.Fatal(err) + } + t.Logf("marshalled: %s", b) + + e, err := lobby.ParseEvent(b) + if err != nil { + t.Fatal(err) + } + t.Logf("unmarshalled: %+v", e) + + if c.e != e { + t.Errorf("expected %+v but got %+v", c.e, e) + } + }) + } +} diff --git a/src/state/lobby/internal/event.go b/src/state/lobby/internal/event.go deleted file mode 100644 index b72c52a..0000000 --- a/src/state/lobby/internal/event.go +++ /dev/null @@ -1,17 +0,0 @@ -package lobby - -type event interface { - lobbyEvent() -} - -type playerJoin struct { - ID int -} - -func (playerJoin) LobbyEvent() {} - -type playerLeave struct { - ID int -} - -func (playerLeave) LobbyEvent() {} diff --git a/src/state/lobby/internal/storage.go b/src/state/lobby/internal/storage.go deleted file mode 100644 index eb2ae4f..0000000 --- a/src/state/lobby/internal/storage.go +++ /dev/null @@ -1,16 +0,0 @@ -package lobby - -import ( - "context" - "io" -) - -type storage interface { - playerIDs(context.Context) ([]int, error) -} - -type DB struct{} - -func (db DB) playerIDs(ctx context.Context) ([]int, error) { - return nil, io.EOF -} diff --git a/src/state/lobby/storage.go b/src/state/lobby/storage.go new file mode 100644 index 0000000..3e6634d --- /dev/null +++ b/src/state/lobby/storage.go @@ -0,0 +1,16 @@ +package lobby + +import ( + "context" + "io" +) + +type Storage interface { + PlayerIDs(context.Context) ([]int, error) +} + +type DB struct{} + +func (db DB) PlayerIDs(ctx context.Context) ([]int, error) { + return nil, io.EOF +}