basketball 0.0.8 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -19
- data/CHANGELOG.md +1 -39
- data/README.md +75 -93
- data/basketball.gemspec +3 -6
- data/exe/{basketball-season-scheduling → basketball-coordinator} +1 -1
- data/exe/{basketball-draft → basketball-room} +1 -1
- data/lib/basketball/app/coordinator_cli.rb +250 -0
- data/lib/basketball/app/coordinator_repository.rb +114 -0
- data/lib/basketball/app/document_repository.rb +67 -0
- data/lib/basketball/app/file_store.rb +38 -0
- data/lib/basketball/app/in_memory_store.rb +42 -0
- data/lib/basketball/app/league_repository.rb +20 -0
- data/lib/basketball/app/league_serializable.rb +54 -0
- data/lib/basketball/{draft/cli.rb → app/room_cli.rb} +74 -80
- data/lib/basketball/app/room_repository.rb +149 -0
- data/lib/basketball/app.rb +20 -0
- data/lib/basketball/draft/assessment.rb +31 -0
- data/lib/basketball/draft/event.rb +3 -2
- data/lib/basketball/draft/front_office.rb +35 -28
- data/lib/basketball/draft/{pick_event.rb → pick.rb} +13 -6
- data/lib/basketball/draft/room.rb +119 -119
- data/lib/basketball/draft/{player_search.rb → scout.rb} +4 -9
- data/lib/basketball/draft/skip.rb +12 -0
- data/lib/basketball/draft.rb +13 -6
- data/lib/basketball/entity.rb +19 -10
- data/lib/basketball/org/league.rb +68 -0
- data/lib/basketball/org/player.rb +26 -0
- data/lib/basketball/{draft → org}/position.rb +3 -2
- data/lib/basketball/org/team.rb +38 -0
- data/lib/basketball/org.rb +12 -0
- data/lib/basketball/season/arena.rb +113 -0
- data/lib/basketball/season/calendar.rb +41 -72
- data/lib/basketball/season/coordinator.rb +186 -128
- data/lib/basketball/season/{preseason_game.rb → exhibition.rb} +2 -1
- data/lib/basketball/season/game.rb +15 -10
- data/lib/basketball/season/matchup.rb +27 -0
- data/lib/basketball/season/opponent.rb +15 -0
- data/lib/basketball/season/{season_game.rb → regular.rb} +2 -1
- data/lib/basketball/season/result.rb +37 -0
- data/lib/basketball/season.rb +12 -13
- data/lib/basketball/value_object.rb +8 -27
- data/lib/basketball/value_object_dsl.rb +30 -0
- data/lib/basketball/version.rb +1 -1
- data/lib/basketball.rb +9 -4
- metadata +37 -44
- data/lib/basketball/draft/league.rb +0 -70
- data/lib/basketball/draft/player.rb +0 -43
- data/lib/basketball/draft/room_serializer.rb +0 -186
- data/lib/basketball/draft/roster.rb +0 -37
- data/lib/basketball/draft/sim_event.rb +0 -23
- data/lib/basketball/draft/skip_event.rb +0 -13
- data/lib/basketball/season/calendar_serializer.rb +0 -94
- data/lib/basketball/season/conference.rb +0 -57
- data/lib/basketball/season/division.rb +0 -43
- data/lib/basketball/season/league.rb +0 -114
- data/lib/basketball/season/league_serializer.rb +0 -99
- data/lib/basketball/season/scheduling_cli.rb +0 -198
- data/lib/basketball/season/team.rb +0 -21
@@ -1,186 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'front_office'
|
4
|
-
require_relative 'player'
|
5
|
-
require_relative 'pick_event'
|
6
|
-
require_relative 'sim_event'
|
7
|
-
require_relative 'skip_event'
|
8
|
-
|
9
|
-
module Basketball
|
10
|
-
module Draft
|
11
|
-
class RoomSerializer
|
12
|
-
EVENT_CLASSES = {
|
13
|
-
'PickEvent' => PickEvent,
|
14
|
-
'SimEvent' => SimEvent,
|
15
|
-
'SkipEvent' => SkipEvent
|
16
|
-
}.freeze
|
17
|
-
|
18
|
-
private_constant :EVENT_CLASSES
|
19
|
-
|
20
|
-
def to_hash(room)
|
21
|
-
{
|
22
|
-
'info' => serialize_info(room),
|
23
|
-
'room' => serialize_room(room),
|
24
|
-
'league' => serialize_league(room)
|
25
|
-
}
|
26
|
-
end
|
27
|
-
|
28
|
-
def from_hash(json)
|
29
|
-
front_offices = deserialize_front_offices(json)
|
30
|
-
players = deserialize_players(json)
|
31
|
-
events = deserialize_events(json, players, front_offices)
|
32
|
-
|
33
|
-
room_opts = {
|
34
|
-
players:,
|
35
|
-
front_offices:,
|
36
|
-
events:
|
37
|
-
}
|
38
|
-
|
39
|
-
room_opts[:rounds] = json.dig('room', 'rounds') if json.dig('room', 'rounds')
|
40
|
-
|
41
|
-
Room.new(**room_opts)
|
42
|
-
end
|
43
|
-
|
44
|
-
def deserialize(string)
|
45
|
-
json = JSON.parse(string)
|
46
|
-
|
47
|
-
from_hash(json)
|
48
|
-
end
|
49
|
-
|
50
|
-
def serialize(room)
|
51
|
-
to_hash(room).to_json
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def serialize_room(room)
|
57
|
-
{
|
58
|
-
'rounds' => room.rounds,
|
59
|
-
'front_offices' => serialize_front_offices(room),
|
60
|
-
'players' => serialize_players(room),
|
61
|
-
'events' => serialize_events(room.events)
|
62
|
-
}
|
63
|
-
end
|
64
|
-
|
65
|
-
def serialize_info(room)
|
66
|
-
{
|
67
|
-
'total_picks' => room.total_picks,
|
68
|
-
'current_round' => room.current_round,
|
69
|
-
'current_round_pick' => room.current_round_pick,
|
70
|
-
'current_front_office' => room.current_front_office&.id,
|
71
|
-
'current_pick' => room.current_pick,
|
72
|
-
'remaining_picks' => room.remaining_picks,
|
73
|
-
'done' => room.done?
|
74
|
-
}
|
75
|
-
end
|
76
|
-
|
77
|
-
def serialize_league(room)
|
78
|
-
league = room.to_league
|
79
|
-
|
80
|
-
rosters = league.rosters.to_h do |roster|
|
81
|
-
[
|
82
|
-
roster.id,
|
83
|
-
{
|
84
|
-
'players' => roster.players.map(&:id)
|
85
|
-
}
|
86
|
-
]
|
87
|
-
end
|
88
|
-
|
89
|
-
{
|
90
|
-
'free_agents' => league.free_agents.map(&:id),
|
91
|
-
'rosters' => rosters
|
92
|
-
}
|
93
|
-
end
|
94
|
-
|
95
|
-
def serialize_front_offices(room)
|
96
|
-
room.front_offices.to_h do |front_office|
|
97
|
-
[
|
98
|
-
front_office.id,
|
99
|
-
{
|
100
|
-
'name' => front_office.name,
|
101
|
-
'fuzz' => front_office.fuzz,
|
102
|
-
'depth' => front_office.depth,
|
103
|
-
'prioritized_positions' => front_office.prioritized_positions.map(&:code)
|
104
|
-
}
|
105
|
-
]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
def serialize_players(room)
|
110
|
-
room.players.to_h do |player|
|
111
|
-
[
|
112
|
-
player.id,
|
113
|
-
{
|
114
|
-
'first_name' => player.first_name,
|
115
|
-
'last_name' => player.last_name,
|
116
|
-
'overall' => player.overall,
|
117
|
-
'position' => player.position.code
|
118
|
-
}
|
119
|
-
]
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
def serialize_events(events)
|
124
|
-
events.map do |event|
|
125
|
-
{
|
126
|
-
'type' => event.class.name.split('::').last,
|
127
|
-
'front_office' => event.front_office.id,
|
128
|
-
'pick' => event.pick,
|
129
|
-
'round' => event.round,
|
130
|
-
'round_pick' => event.round_pick
|
131
|
-
}.tap do |hash|
|
132
|
-
hash['player'] = event.player.id if event.respond_to?(:player)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def deserialize_front_offices(json)
|
138
|
-
(json.dig('room', 'front_offices') || []).map do |id, front_office_hash|
|
139
|
-
prioritized_positions = (front_office_hash['prioritized_positions'] || []).map do |v|
|
140
|
-
Position.new(v)
|
141
|
-
end
|
142
|
-
|
143
|
-
front_office_opts = {
|
144
|
-
id:,
|
145
|
-
name: front_office_hash['name'],
|
146
|
-
prioritized_positions:,
|
147
|
-
fuzz: front_office_hash['fuzz'],
|
148
|
-
depth: front_office_hash['depth']
|
149
|
-
}
|
150
|
-
|
151
|
-
FrontOffice.new(**front_office_opts)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def deserialize_players(json)
|
156
|
-
(json.dig('room', 'players') || []).map do |id, player_hash|
|
157
|
-
player_opts = {
|
158
|
-
id:,
|
159
|
-
first_name: player_hash['first_name'],
|
160
|
-
last_name: player_hash['last_name'],
|
161
|
-
overall: player_hash['overall'],
|
162
|
-
position: Position.new(player_hash['position'])
|
163
|
-
}
|
164
|
-
|
165
|
-
Player.new(**player_opts)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
def deserialize_events(json, players, front_offices)
|
170
|
-
(json.dig('room', 'events') || []).map do |event_hash|
|
171
|
-
event_opts = event_hash.slice('pick', 'round', 'round_pick').merge(
|
172
|
-
front_office: front_offices.find { |t| t.id == event_hash['front_office'] }
|
173
|
-
)
|
174
|
-
|
175
|
-
class_constant = EVENT_CLASSES.fetch(event_hash['type'])
|
176
|
-
|
177
|
-
if [PickEvent, SimEvent].include?(class_constant)
|
178
|
-
event_opts[:player] = players.find { |p| p.id == event_hash['player'] }
|
179
|
-
end
|
180
|
-
|
181
|
-
class_constant.new(**event_opts)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Draft
|
5
|
-
class Roster < Entity
|
6
|
-
class PlayerRequiredError < StandardError; end
|
7
|
-
|
8
|
-
attr_reader :name, :players
|
9
|
-
|
10
|
-
def initialize(id:, name: '', players: [])
|
11
|
-
super(id)
|
12
|
-
|
13
|
-
@name = name.to_s
|
14
|
-
@players = players.each { |p| register!(p) }
|
15
|
-
|
16
|
-
freeze
|
17
|
-
end
|
18
|
-
|
19
|
-
def registered?(player)
|
20
|
-
players.include?(player)
|
21
|
-
end
|
22
|
-
|
23
|
-
def sign!(player)
|
24
|
-
raise PlayerRequiredError, 'player is required' unless player
|
25
|
-
raise PlayerAlreadyRegisteredError, "#{player} already registered for #{id}" if registered?(player)
|
26
|
-
|
27
|
-
players << player
|
28
|
-
|
29
|
-
self
|
30
|
-
end
|
31
|
-
|
32
|
-
def to_s
|
33
|
-
(["[#{super}] #{name} Roster"] + players.map(&:to_s)).join("\n")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Draft
|
5
|
-
class SimEvent < Event
|
6
|
-
attr_reader_value :player
|
7
|
-
|
8
|
-
def initialize(front_office:, player:, pick:, round:, round_pick:)
|
9
|
-
super(front_office:, pick:, round:, round_pick:)
|
10
|
-
|
11
|
-
raise ArgumentError, 'player required' unless player
|
12
|
-
|
13
|
-
@player = player
|
14
|
-
|
15
|
-
freeze
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_s
|
19
|
-
"#{player} auto-picked #{super}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,94 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'game'
|
4
|
-
require_relative 'preseason_game'
|
5
|
-
require_relative 'season_game'
|
6
|
-
|
7
|
-
module Basketball
|
8
|
-
module Season
|
9
|
-
class CalendarSerializer
|
10
|
-
GAME_CLASSES = {
|
11
|
-
'PreseasonGame' => PreseasonGame,
|
12
|
-
'SeasonGame' => SeasonGame
|
13
|
-
}.freeze
|
14
|
-
|
15
|
-
def to_hash(calendar)
|
16
|
-
teams = calendar.games.flat_map(&:teams).uniq
|
17
|
-
|
18
|
-
{
|
19
|
-
'year' => calendar.preseason_start_date.year,
|
20
|
-
'teams' => serialize_teams(teams),
|
21
|
-
'games' => serialize_games(calendar.games)
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
def from_hash(json)
|
26
|
-
Calendar.new(
|
27
|
-
year: json['year'].to_i,
|
28
|
-
games: deserialize_games(json)
|
29
|
-
)
|
30
|
-
end
|
31
|
-
|
32
|
-
def deserialize(string)
|
33
|
-
json = JSON.parse(string)
|
34
|
-
|
35
|
-
from_hash(json)
|
36
|
-
end
|
37
|
-
|
38
|
-
def serialize(calendar)
|
39
|
-
to_hash(calendar).to_json
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
## Deserialization
|
45
|
-
|
46
|
-
def deserialize_games(json)
|
47
|
-
teams = deserialize_teams(json['teams'])
|
48
|
-
|
49
|
-
(json['games'] || []).map do |game_hash|
|
50
|
-
GAME_CLASSES.fetch(game_hash['type']).new(
|
51
|
-
date: Date.parse(game_hash['date']),
|
52
|
-
home_team: teams.fetch(game_hash['home_team']),
|
53
|
-
away_team: teams.fetch(game_hash['away_team'])
|
54
|
-
)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def deserialize_teams(teams)
|
59
|
-
(teams || []).to_h do |id, team_hash|
|
60
|
-
team = Team.new(id:, name: team_hash['name'])
|
61
|
-
|
62
|
-
[
|
63
|
-
team.id,
|
64
|
-
team
|
65
|
-
]
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
## Serialization
|
70
|
-
|
71
|
-
def serialize_teams(teams)
|
72
|
-
teams.to_h do |team|
|
73
|
-
[
|
74
|
-
team.id,
|
75
|
-
{
|
76
|
-
'name' => team.name
|
77
|
-
}
|
78
|
-
]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def serialize_games(games)
|
83
|
-
games.sort_by(&:date).map do |game|
|
84
|
-
{
|
85
|
-
'type' => game.class.name.split('::').last,
|
86
|
-
'date' => game.date.to_s,
|
87
|
-
'home_team' => game.home_team.id,
|
88
|
-
'away_team' => game.away_team.id
|
89
|
-
}
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
@@ -1,57 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Season
|
5
|
-
class Conference < Entity
|
6
|
-
DIVISIONS_SIZE = 3
|
7
|
-
|
8
|
-
attr_reader :name, :divisions
|
9
|
-
|
10
|
-
def initialize(id:, name: '', divisions: [])
|
11
|
-
super(id)
|
12
|
-
|
13
|
-
@name = name.to_s
|
14
|
-
@divisions = []
|
15
|
-
|
16
|
-
divisions.each { |d| register_division!(d) }
|
17
|
-
|
18
|
-
if divisions.length != DIVISIONS_SIZE
|
19
|
-
raise BadDivisionsSizeError, "#{id} should have exactly #{DIVISIONS_SIZE} divisions"
|
20
|
-
end
|
21
|
-
|
22
|
-
freeze
|
23
|
-
end
|
24
|
-
|
25
|
-
def to_s
|
26
|
-
(["[#{super}] #{name}"] + divisions.map(&:to_s)).join("\n")
|
27
|
-
end
|
28
|
-
|
29
|
-
def division?(division)
|
30
|
-
divisions.include?(division)
|
31
|
-
end
|
32
|
-
|
33
|
-
def teams
|
34
|
-
divisions.flat_map(&:teams)
|
35
|
-
end
|
36
|
-
|
37
|
-
def team?(team)
|
38
|
-
teams.include?(team)
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def register_division!(division)
|
44
|
-
raise ArgumentError, 'division is required' unless division
|
45
|
-
raise DivisionAlreadyRegisteredError, "#{division} already registered" if division?(division)
|
46
|
-
|
47
|
-
division.teams.each do |team|
|
48
|
-
raise TeamAlreadyRegisteredError, "#{team} already registered" if team?(team)
|
49
|
-
end
|
50
|
-
|
51
|
-
divisions << division
|
52
|
-
|
53
|
-
self
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Season
|
5
|
-
class Division < Entity
|
6
|
-
TEAMS_SIZE = 5
|
7
|
-
|
8
|
-
attr_reader :name, :teams
|
9
|
-
|
10
|
-
def initialize(id:, name: '', teams: [])
|
11
|
-
super(id)
|
12
|
-
|
13
|
-
@name = name.to_s
|
14
|
-
@teams = []
|
15
|
-
|
16
|
-
teams.each { |t| register_team!(t) }
|
17
|
-
|
18
|
-
raise BadTeamsSizeError, "#{id} should have exactly #{TEAMS_SIZE} teams" if teams.length != TEAMS_SIZE
|
19
|
-
|
20
|
-
freeze
|
21
|
-
end
|
22
|
-
|
23
|
-
def to_s
|
24
|
-
(["[#{super}] #{name}"] + teams.map(&:to_s)).join("\n")
|
25
|
-
end
|
26
|
-
|
27
|
-
def team?(team)
|
28
|
-
teams.include?(team)
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def register_team!(team)
|
34
|
-
raise ArgumentError, 'team is required' unless team
|
35
|
-
raise TeamAlreadyRegisteredError, "#{team} already registered" if team?(team)
|
36
|
-
|
37
|
-
teams << team
|
38
|
-
|
39
|
-
self
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,114 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Season
|
5
|
-
class League
|
6
|
-
class UnknownTeamError < StandardError; end
|
7
|
-
|
8
|
-
class << self
|
9
|
-
def generate_random; end
|
10
|
-
end
|
11
|
-
|
12
|
-
CONFERENCES_SIZE = 2
|
13
|
-
|
14
|
-
attr_reader :conferences
|
15
|
-
|
16
|
-
def initialize(conferences: [])
|
17
|
-
@conferences = []
|
18
|
-
|
19
|
-
conferences.each { |c| register_conference!(c) }
|
20
|
-
|
21
|
-
if conferences.length != CONFERENCES_SIZE
|
22
|
-
raise BadConferencesSizeError, "there has to be #{CONFERENCES_SIZE} conferences"
|
23
|
-
end
|
24
|
-
|
25
|
-
freeze
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_s
|
29
|
-
(['League'] + conferences.map(&:to_s)).join("\n")
|
30
|
-
end
|
31
|
-
|
32
|
-
def divisions
|
33
|
-
conferences.flat_map(&:divisions)
|
34
|
-
end
|
35
|
-
|
36
|
-
def conference?(conference)
|
37
|
-
conferences.include?(conference)
|
38
|
-
end
|
39
|
-
|
40
|
-
def division?(division)
|
41
|
-
divisions.include?(division)
|
42
|
-
end
|
43
|
-
|
44
|
-
def team?(team)
|
45
|
-
teams.include?(team)
|
46
|
-
end
|
47
|
-
|
48
|
-
def teams
|
49
|
-
conferences.flat_map do |conference|
|
50
|
-
conference.divisions.flat_map(&:teams)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def conference_for(team)
|
55
|
-
conferences.find { |c| c.divisions.find { |d| d.teams.include?(team) } }
|
56
|
-
end
|
57
|
-
|
58
|
-
def division_for(team)
|
59
|
-
conference_for(team)&.divisions&.find { |d| d.teams.include?(team) }
|
60
|
-
end
|
61
|
-
|
62
|
-
# Same conference, same division
|
63
|
-
def division_opponents_for(team)
|
64
|
-
division = division_for(team)
|
65
|
-
|
66
|
-
return nil unless division
|
67
|
-
|
68
|
-
division.teams - [team]
|
69
|
-
end
|
70
|
-
|
71
|
-
# Same conference, different division
|
72
|
-
def cross_division_opponents_for(team)
|
73
|
-
conference = conference_for(team)
|
74
|
-
division = division_for(team)
|
75
|
-
|
76
|
-
return nil unless conference && division
|
77
|
-
|
78
|
-
other_divisions = conference.divisions - [division]
|
79
|
-
|
80
|
-
other_divisions.flat_map(&:teams)
|
81
|
-
end
|
82
|
-
|
83
|
-
# Different conference
|
84
|
-
def cross_conference_opponents_for(team)
|
85
|
-
conference = conference_for(team)
|
86
|
-
|
87
|
-
return nil unless conference
|
88
|
-
|
89
|
-
other_conferences = conferences - [conference]
|
90
|
-
|
91
|
-
other_conferences.flat_map { |c| c.divisions.flat_map(&:teams) }
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def register_conference!(conference)
|
97
|
-
raise ArgumentError, 'conference is required' unless conference
|
98
|
-
raise ConferenceAlreadyRegisteredError, "#{conference} already registered" if conference?(conference)
|
99
|
-
|
100
|
-
conference.divisions.each do |division|
|
101
|
-
raise DivisionAlreadyRegisteredError, "#{division} already registered" if division?(division)
|
102
|
-
|
103
|
-
division.teams.each do |team|
|
104
|
-
raise TeamAlreadyRegisteredError, "#{team} already registered" if team?(team)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
conferences << conference
|
109
|
-
|
110
|
-
self
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Basketball
|
4
|
-
module Season
|
5
|
-
class LeagueSerializer
|
6
|
-
def to_hash(league)
|
7
|
-
{
|
8
|
-
'conferences' => serialize_conferences(league.conferences)
|
9
|
-
}
|
10
|
-
end
|
11
|
-
|
12
|
-
def from_hash(json)
|
13
|
-
conferences = deserialize_conferences(json['conferences'])
|
14
|
-
|
15
|
-
League.new(conferences:)
|
16
|
-
end
|
17
|
-
|
18
|
-
def deserialize(string)
|
19
|
-
json = JSON.parse(string)
|
20
|
-
|
21
|
-
from_hash(json)
|
22
|
-
end
|
23
|
-
|
24
|
-
def serialize(league)
|
25
|
-
to_hash(league).to_json
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
## Deserialization
|
31
|
-
|
32
|
-
def deserialize_conferences(conferences)
|
33
|
-
(conferences || []).map do |conference_id, conference_hash|
|
34
|
-
Conference.new(
|
35
|
-
id: conference_id,
|
36
|
-
name: conference_hash['name'],
|
37
|
-
divisions: deserialize_divisions(conference_hash['divisions'])
|
38
|
-
)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def deserialize_divisions(divisions)
|
43
|
-
(divisions || []).map do |division_id, division_hash|
|
44
|
-
Division.new(
|
45
|
-
id: division_id,
|
46
|
-
name: division_hash['name'],
|
47
|
-
teams: deserialize_teams(division_hash['teams'])
|
48
|
-
)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def deserialize_teams(teams)
|
53
|
-
(teams || []).map do |team_id, team_hash|
|
54
|
-
Team.new(
|
55
|
-
id: team_id,
|
56
|
-
name: team_hash['name']
|
57
|
-
)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
## Serialization
|
62
|
-
|
63
|
-
def serialize_conferences(conferences)
|
64
|
-
conferences.to_h do |conference|
|
65
|
-
[
|
66
|
-
conference.id,
|
67
|
-
{
|
68
|
-
'name' => conference.name,
|
69
|
-
'divisions' => serialize_divisions(conference.divisions)
|
70
|
-
}
|
71
|
-
]
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def serialize_divisions(divisions)
|
76
|
-
divisions.to_h do |division|
|
77
|
-
[
|
78
|
-
division.id,
|
79
|
-
{
|
80
|
-
'name' => division.name,
|
81
|
-
'teams' => serialize_teams(division.teams)
|
82
|
-
}
|
83
|
-
]
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def serialize_teams(teams)
|
88
|
-
teams.to_h do |team|
|
89
|
-
[
|
90
|
-
team.id,
|
91
|
-
{
|
92
|
-
'name' => team.name
|
93
|
-
}
|
94
|
-
]
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|