defmodule WinticketRaceParser.FromRawMap do
alias WinticketRaceParser.Structs.{
RaceContext,
Race,
Cup,
OddsItem,
OddsCategory,
ResultItem,
PlayerDetail,
Player,
ResultHistory,
ResultHistoryRace,
PlayerRecord,
PlayerRecordLegType,
PlayerRecordPercent,
PlayerRecordSB,
Venue
}
def parse(map) do
str_map = stringify_keys(map)
players =
str_map["players"]
|> Enum.map(fn p ->
Player.validate(%{
number: p["number"],
absent: p["absent"],
player_id: p["player_id"],
player: PlayerDetail.validate(to_atom_map(p["player"])),
record:
PlayerRecord.validate(%{
countable: p["record"]["countable"],
style: p["record"]["style"],
race_point: p["record"]["race_point"],
comment: p["record"]["comment"],
sb: PlayerRecordSB.validate(to_atom_map(p["record"]["sb"])),
percent: PlayerRecordPercent.validate(to_atom_map(p["record"]["percent"])),
leg_type: PlayerRecordLegType.validate(to_atom_map(p["record"]["leg_type"]))
}),
current_cup:
Enum.map(p["current_cup"], fn r ->
ResultHistoryRace.validate(to_atom_map(r))
end),
previous_cup:
Enum.map(p["previous_cup"], fn r ->
ResultHistoryRace.validate(to_atom_map(r))
end),
latest_cups:
Enum.map(p["latest_cups"], fn lc ->
ResultHistory.validate(%{
race_point: lc["race_point"],
cup_id: lc["cup_id"],
races:
Enum.map(lc["races"], fn r ->
ResultHistoryRace.validate(to_atom_map(r))
end)
})
end)
})
end)
line = str_map["line"]
results =
str_map["results"]
|> Enum.map(fn r ->
ResultItem.validate(to_atom_map(r))
end)
odds =
OddsCategory.validate(%{
nishatan:
str_map["odds"]["nishatan"] |> Enum.map(fn v -> OddsItem.validate(to_atom_map(v)) end),
nishafuku:
str_map["odds"]["nishafuku"] |> Enum.map(fn v -> OddsItem.validate(to_atom_map(v)) end),
sanrenpuku:
str_map["odds"]["sanrenpuku"] |> Enum.map(fn v -> OddsItem.validate(to_atom_map(v)) end),
sanrentan:
str_map["odds"]["sanrentan"] |> Enum.map(fn v -> OddsItem.validate(to_atom_map(v)) end)
})
race = Race.validate(to_atom_map(str_map["race"]))
cup = Cup.validate(to_atom_map(str_map["cup"]))
is_defect = line == nil or race.distance == 0
is_finish = results != []
venue = Venue.validate(to_atom_map(str_map["venue"]))
RaceContext.validate(%{
players: players,
line: line,
results: results,
odds: odds,
race: race,
cup: cup,
venue: venue,
is_defect: is_defect,
is_finish: is_finish
})
end
defp to_atom_map(map) do
map
|> Enum.into(Map.new(), fn {k, v} -> {String.to_atom(k), v} end)
end
defp stringify_keys(nil), do: nil
defp stringify_keys(%DateTime{} = dt) do
dt
end
defp stringify_keys(%{} = map) do
map
|> Enum.map(fn {k, v} ->
next_k =
if is_atom(k),
do: Atom.to_string(k),
else: k
{next_k, stringify_keys(v)}
end)
|> Enum.into(%{})
end
defp stringify_keys([head | rest]) do
[stringify_keys(head) | stringify_keys(rest)]
end
defp stringify_keys(not_a_map) do
not_a_map
end
end