feat: game lobby service
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
package redisstate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"galaxy/lobby/internal/domain/common"
|
||||
"galaxy/lobby/internal/domain/membership"
|
||||
)
|
||||
|
||||
// membershipRecord stores the strict Redis JSON shape used for one
|
||||
// membership record.
|
||||
type membershipRecord struct {
|
||||
MembershipID string `json:"membership_id"`
|
||||
GameID string `json:"game_id"`
|
||||
UserID string `json:"user_id"`
|
||||
RaceName string `json:"race_name"`
|
||||
CanonicalKey string `json:"canonical_key"`
|
||||
Status membership.Status `json:"status"`
|
||||
JoinedAtMS int64 `json:"joined_at_ms"`
|
||||
RemovedAtMS *int64 `json:"removed_at_ms,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalMembership encodes record into the strict Redis JSON shape used
|
||||
// for membership records. The record is re-validated before marshalling.
|
||||
func MarshalMembership(record membership.Membership) ([]byte, error) {
|
||||
if err := record.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("marshal redis membership record: %w", err)
|
||||
}
|
||||
|
||||
stored := membershipRecord{
|
||||
MembershipID: record.MembershipID.String(),
|
||||
GameID: record.GameID.String(),
|
||||
UserID: record.UserID,
|
||||
RaceName: record.RaceName,
|
||||
CanonicalKey: record.CanonicalKey,
|
||||
Status: record.Status,
|
||||
JoinedAtMS: record.JoinedAt.UTC().UnixMilli(),
|
||||
RemovedAtMS: optionalUnixMilli(record.RemovedAt),
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(stored)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal redis membership record: %w", err)
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
// UnmarshalMembership decodes payload from the strict Redis JSON shape
|
||||
// used for membership records. The decoded record is validated before
|
||||
// returning.
|
||||
func UnmarshalMembership(payload []byte) (membership.Membership, error) {
|
||||
var stored membershipRecord
|
||||
if err := decodeStrictJSON("decode redis membership record", payload, &stored); err != nil {
|
||||
return membership.Membership{}, err
|
||||
}
|
||||
|
||||
record := membership.Membership{
|
||||
MembershipID: common.MembershipID(stored.MembershipID),
|
||||
GameID: common.GameID(stored.GameID),
|
||||
UserID: stored.UserID,
|
||||
RaceName: stored.RaceName,
|
||||
CanonicalKey: stored.CanonicalKey,
|
||||
Status: stored.Status,
|
||||
JoinedAt: time.UnixMilli(stored.JoinedAtMS).UTC(),
|
||||
RemovedAt: inflateOptionalTime(stored.RemovedAtMS),
|
||||
}
|
||||
if err := record.Validate(); err != nil {
|
||||
return membership.Membership{}, fmt.Errorf("decode redis membership record: %w", err)
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
||||
Reference in New Issue
Block a user