1use std::collections::HashMap;
2
3use chrono::{DateTime, Utc, serde::ts_seconds};
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize)]
7pub(crate) struct LiveScoreQueryParams {
8 pub(crate) offset: u8,
9}
10
11#[derive(Debug, Deserialize)]
12#[serde(rename_all = "camelCase")]
13pub struct LiveScoresResponse {
14 pub matches: Vec<Match>,
15}
16
17#[derive(Debug, Deserialize, Clone)]
18#[serde(rename_all = "camelCase")]
19pub struct Match {
20 pub id: String,
21 pub period: usize,
30 pub time: Option<usize>,
31 pub status: Status,
32 pub comp: Competition,
33 #[serde(with = "ts_seconds")]
34 pub date: DateTime<Utc>,
35 pub home: Team,
36 pub away: Team,
37 pub score: Option<HashMap<ScoreKey, Score>>,
38 pub events: Option<Vec<Event>>,
39 #[serde(with = "ts_seconds")]
40 pub updated: DateTime<Utc>,
41}
42
43impl Match {
44 pub fn try_get_score(&self, score_key: &ScoreKey) -> Option<&Score> {
45 self.score.as_ref().and_then(|scores| scores.get(score_key))
46 }
47}
48
49#[derive(Debug, Deserialize, Clone)]
50#[serde(rename_all = "camelCase", tag = "entity_type")]
51pub enum Event {
52 Sub(SubEvent),
53 Goal(GoalEvent),
54 Card(CardEvent),
55 Var(VAREvent),
56 Pen(PenaltyEvent),
57}
58
59impl Event {
60 pub fn get_team_id(&self) -> &String {
61 match self {
62 Event::Sub(sub_event) => &sub_event.team_id,
63 Event::Goal(goal_event) => &goal_event.team_id,
64 Event::Card(card_event) => &card_event.team_id,
65 Event::Var(varevent) => &varevent.team_id,
66 Event::Pen(penalty_event) => &penalty_event.team_id,
67 }
68 }
69
70 pub fn get_time_str(&self) -> Option<&String> {
71 match self {
72 Event::Sub(sub_event) => sub_event.time_str.as_ref(),
73 Event::Goal(goal_event) => goal_event.time_str.as_ref(),
74 Event::Card(card_event) => card_event.time_str.as_ref(),
75 Event::Var(varevent) => varevent.time_str.as_ref(),
76 Event::Pen(penalty_event) => penalty_event.time_str.as_ref(),
77 }
78 }
79}
80
81#[derive(Debug, Deserialize, Clone)]
82#[serde(rename_all = "camelCase", tag = "entity_type")]
83pub struct PenaltyEvent {
84 pub period_id: u8,
85 pub min: u16,
86 pub time_str: Option<String>,
87 pub team_id: String,
88 pub player_id: String,
89 pub player_name: String,
90 pub outcome: PenaltyOutcome,
91 pub pen_num: usize,
92}
93
94#[derive(Debug, Deserialize, Clone)]
95#[serde(rename_all = "camelCase")]
96pub enum PenaltyOutcome {
97 Saved,
98 Scored,
99 Missed,
100}
101
102#[derive(Debug, Deserialize, Clone)]
103#[serde(rename_all = "camelCase")]
104pub struct VAREvent {
105 pub period_id: u8,
106 pub min: u16,
107 pub time_str: Option<String>,
108 pub team_id: String,
109 pub player_id: String,
110 pub player_name: String,
111 #[serde(rename = "type")]
112 pub var_type: String,
113 pub outcome: Option<String>,
114 pub decision: String,
115}
116
117#[derive(Debug, Deserialize, Clone)]
118#[serde(rename_all = "camelCase")]
119pub struct CardEvent {
120 pub period_id: u8,
121 pub min: u16,
122 pub time_str: Option<String>,
123 pub player_name: Option<String>,
124 pub reason: Option<String>,
125 pub team_id: String,
126 #[serde(rename = "type")]
127 pub card_type: Card,
128}
129
130#[derive(Debug, Deserialize, Clone)]
131pub enum Card {
132 #[serde(rename = "YC")]
133 Yellow,
134 #[serde(rename = "Y2C")]
135 SecondYellow,
136 #[serde(rename = "RC")]
137 Red,
138}
139
140#[derive(Debug, Deserialize, Clone)]
141#[serde(rename_all = "camelCase")]
142pub struct GoalEvent {
143 pub period_id: u8,
144 pub min: u16,
145 pub time_str: Option<String>,
146 pub team_id: String,
147 pub player_id: String,
148 pub player_name: String,
149 pub player_2_name: Option<String>,
150 #[serde(rename = "type")]
151 pub goal_type: GoalType,
152 pub score: Option<[u8; 2]>,
153}
154
155#[derive(Debug, Deserialize, Clone, Copy)]
156pub enum GoalType {
157 #[serde(rename = "G")]
158 Goal,
159 #[serde(rename = "PG")]
160 Penalty,
161 #[serde(rename = "OG")]
162 OwnGoal,
163}
164
165#[derive(Debug, Deserialize, Clone)]
166#[serde(rename_all = "camelCase")]
167pub struct SubEvent {
168 pub period_id: u8,
169 pub min: u16,
170 pub time_str: Option<String>,
171 pub team_id: String,
172 pub player_id: String,
173 pub player_name: String,
174 pub player2_id: String,
175 pub player2_name: String,
176}
177
178#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Debug, Deserialize, Clone, Copy)]
179#[serde(rename_all = "camelCase")]
180pub enum ScoreKey {
181 Ft,
182 Ht,
183 Total,
184 Aggregate,
185 TotalUnconfirmed,
186 Pen,
187 Et,
188}
189
190#[derive(Debug, Deserialize, Clone, Copy, Default)]
191#[serde(rename_all = "camelCase")]
192pub struct Score {
193 pub home: u8,
194 pub away: u8,
195}
196
197#[derive(Debug, Deserialize, Clone)]
198#[serde(rename_all = "camelCase")]
199pub struct Competition {
200 pub id: String,
201 pub name: String,
202 pub country: Country,
203}
204
205#[derive(Debug, Deserialize, Clone)]
206#[serde(rename_all = "camelCase")]
207pub struct Country {
208 pub id: String,
209 pub full_name: String,
210}
211
212#[derive(Debug, Deserialize, Clone)]
214#[serde(rename_all = "camelCase")]
215pub struct Team {
216 pub id: Option<String>,
217 pub name: Option<String>,
218}
219
220#[derive(Debug, Deserialize, Clone, Copy)]
221#[serde(rename_all = "camelCase")]
222pub enum Status {
223 Played,
224 Fixture,
225 Playing,
226 Postponed,
227}