feat: game lobby service
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package redisstate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"galaxy/lobby/internal/domain/common"
|
||||
"galaxy/lobby/internal/domain/invite"
|
||||
)
|
||||
|
||||
// inviteRecord stores the strict Redis JSON shape used for one invite
|
||||
// record.
|
||||
type inviteRecord struct {
|
||||
InviteID string `json:"invite_id"`
|
||||
GameID string `json:"game_id"`
|
||||
InviterUserID string `json:"inviter_user_id"`
|
||||
InviteeUserID string `json:"invitee_user_id"`
|
||||
RaceName string `json:"race_name,omitempty"`
|
||||
Status invite.Status `json:"status"`
|
||||
CreatedAtMS int64 `json:"created_at_ms"`
|
||||
ExpiresAtMS int64 `json:"expires_at_ms"`
|
||||
DecidedAtMS *int64 `json:"decided_at_ms,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalInvite encodes record into the strict Redis JSON shape used for
|
||||
// invite records. The record is re-validated before marshalling.
|
||||
func MarshalInvite(record invite.Invite) ([]byte, error) {
|
||||
if err := record.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("marshal redis invite record: %w", err)
|
||||
}
|
||||
|
||||
stored := inviteRecord{
|
||||
InviteID: record.InviteID.String(),
|
||||
GameID: record.GameID.String(),
|
||||
InviterUserID: record.InviterUserID,
|
||||
InviteeUserID: record.InviteeUserID,
|
||||
RaceName: record.RaceName,
|
||||
Status: record.Status,
|
||||
CreatedAtMS: record.CreatedAt.UTC().UnixMilli(),
|
||||
ExpiresAtMS: record.ExpiresAt.UTC().UnixMilli(),
|
||||
DecidedAtMS: optionalUnixMilli(record.DecidedAt),
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(stored)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal redis invite record: %w", err)
|
||||
}
|
||||
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
// UnmarshalInvite decodes payload from the strict Redis JSON shape used
|
||||
// for invite records. The decoded record is validated before returning.
|
||||
func UnmarshalInvite(payload []byte) (invite.Invite, error) {
|
||||
var stored inviteRecord
|
||||
if err := decodeStrictJSON("decode redis invite record", payload, &stored); err != nil {
|
||||
return invite.Invite{}, err
|
||||
}
|
||||
|
||||
record := invite.Invite{
|
||||
InviteID: common.InviteID(stored.InviteID),
|
||||
GameID: common.GameID(stored.GameID),
|
||||
InviterUserID: stored.InviterUserID,
|
||||
InviteeUserID: stored.InviteeUserID,
|
||||
RaceName: stored.RaceName,
|
||||
Status: stored.Status,
|
||||
CreatedAt: time.UnixMilli(stored.CreatedAtMS).UTC(),
|
||||
ExpiresAt: time.UnixMilli(stored.ExpiresAtMS).UTC(),
|
||||
DecidedAt: inflateOptionalTime(stored.DecidedAtMS),
|
||||
}
|
||||
if err := record.Validate(); err != nil {
|
||||
return invite.Invite{}, fmt.Errorf("decode redis invite record: %w", err)
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
||||
Reference in New Issue
Block a user