-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathservice.go
103 lines (90 loc) · 2.85 KB
/
service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package play
import (
"context"
"errors"
"fmt"
"time"
"github.com/Haraj-backend/hex-monscape/internal/core/entity"
"gopkg.in/validator.v2"
)
var (
ErrGameNotFound = errors.New("game is not found")
ErrPartnerNotFound = errors.New("partner is not found")
)
type Service interface {
// GetAvailablePartners returns monsters that available to be selected as player partner.
GetAvailablePartners(ctx context.Context) ([]entity.Monster, error)
// NewGame is used for initiating new game in storage. If the given `partnerID` not found in storage,
// it returns `ErrPartnerNotFound`. Upon success it returns game instance that being saved on storage.
NewGame(ctx context.Context, playerName string, partnerID string) (*entity.Game, error)
// GetGame returns game instance from storage from given game id. Upon game is not found, it returns
// `ErrGameNotFound`.
GetGame(ctx context.Context, gameID string) (*entity.Game, error)
}
type service struct {
gameStorage GameStorage
partnerStorage PartnerStorage
}
func (s *service) GetAvailablePartners(ctx context.Context) ([]entity.Monster, error) {
partners, err := s.partnerStorage.GetAvailablePartners(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get available partners due: %w", err)
}
return partners, nil
}
func (s *service) NewGame(ctx context.Context, playerName string, partnerID string) (*entity.Game, error) {
// get partner instance
partner, err := s.partnerStorage.GetPartner(ctx, partnerID)
if err != nil {
return nil, fmt.Errorf("unable to fetch partner instance due: %w", err)
}
if partner == nil {
return nil, ErrPartnerNotFound
}
// initiate new game instance
cfg := entity.GameConfig{
PlayerName: playerName,
Partner: partner,
CreatedAt: time.Now().Unix(),
}
game, err := entity.NewGame(cfg)
if err != nil {
return nil, fmt.Errorf("unable to initialize game instance due: %w", err)
}
// store the game instance on storage
err = s.gameStorage.SaveGame(ctx, *game)
if err != nil {
return nil, fmt.Errorf("unable to save game instance due: %w", err)
}
return game, nil
}
func (s *service) GetGame(ctx context.Context, gameID string) (*entity.Game, error) {
// get game instance from storage
game, err := s.gameStorage.GetGame(ctx, gameID)
if err != nil {
return nil, fmt.Errorf("unable to get game instance due: %w", err)
}
if game == nil {
return nil, ErrGameNotFound
}
return game, nil
}
type ServiceConfig struct {
GameStorage GameStorage `validate:"nonnil"`
PartnerStorage PartnerStorage `validate:"nonnil"`
}
func (c ServiceConfig) Validate() error {
return validator.Validate(c)
}
// NewService returns new instance of service.
func NewService(cfg ServiceConfig) (Service, error) {
err := cfg.Validate()
if err != nil {
return nil, err
}
s := &service{
gameStorage: cfg.GameStorage,
partnerStorage: cfg.PartnerStorage,
}
return s, nil
}