1use serde::Serialize;
5use serde::de::{Deserialize, Deserializer, IgnoredAny, SeqAccess, Visitor};
6use std::fmt;
7
8use crate::overview::handle_unknown;
9
10#[derive(Debug, Clone, Serialize)]
11pub struct OverviewData {
12 pub runes: Runes,
13 pub summoner_spells: SummonerSpells,
14 pub starting_items: Items,
15 pub core_items: Items,
16 pub abilities: Abilities,
17 pub item_4_options: Vec<LateItem>,
18 pub item_5_options: Vec<LateItem>,
19 pub item_6_options: Vec<LateItem>,
20 pub wins: i64,
21 pub matches: i64,
22 pub low_sample_size: bool,
23 pub shards: Shards,
24}
25
26#[derive(Debug, Clone, Serialize)]
27pub struct Runes {
28 pub matches: i64,
29 pub wins: i64,
30 pub primary_style_id: i64,
31 pub secondary_style_id: i64,
32 pub rune_ids: Vec<i64>,
33}
34
35impl<'de> Deserialize<'de> for Runes {
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: Deserializer<'de>,
39 {
40 struct RunesVisitor;
41
42 impl<'de> Visitor<'de> for RunesVisitor {
43 type Value = Runes;
44
45 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
46 formatter.write_str("rune stats")
47 }
48
49 fn visit_seq<V>(self, mut visitor: V) -> Result<Runes, V::Error>
50 where
51 V: SeqAccess<'de>,
52 {
53 Ok(Runes {
54 matches: handle_unknown(visitor.next_element::<i64>()),
55 wins: handle_unknown(visitor.next_element::<i64>()),
56 primary_style_id: handle_unknown(visitor.next_element::<i64>()),
57 secondary_style_id: handle_unknown(visitor.next_element::<i64>()),
58 rune_ids: handle_unknown(visitor.next_element::<Vec<i64>>()),
59 })
60 }
61 }
62
63 deserializer.deserialize_seq(RunesVisitor)
64 }
65}
66
67#[derive(Debug, Clone, Serialize)]
68pub struct SummonerSpells {
69 pub matches: i64,
70 pub wins: i64,
71 pub spell_ids: Vec<i64>,
72}
73
74impl<'de> Deserialize<'de> for SummonerSpells {
75 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
76 where
77 D: Deserializer<'de>,
78 {
79 struct SummonerSpellsVisitor;
80
81 impl<'de> Visitor<'de> for SummonerSpellsVisitor {
82 type Value = SummonerSpells;
83
84 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
85 formatter.write_str("summoner spells")
86 }
87
88 fn visit_seq<V>(self, mut visitor: V) -> Result<SummonerSpells, V::Error>
89 where
90 V: SeqAccess<'de>,
91 {
92 Ok(SummonerSpells {
93 matches: handle_unknown(visitor.next_element::<i64>()),
94 wins: handle_unknown(visitor.next_element::<i64>()),
95 spell_ids: handle_unknown(visitor.next_element::<Vec<i64>>()),
96 })
97 }
98 }
99
100 deserializer.deserialize_seq(SummonerSpellsVisitor)
101 }
102}
103
104#[derive(Debug, Clone, Serialize)]
105pub struct Items {
106 pub matches: i64,
107 pub wins: i64,
108 pub item_ids: Vec<i64>,
109}
110
111impl<'de> Deserialize<'de> for Items {
112 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
113 where
114 D: Deserializer<'de>,
115 {
116 struct ItemsVisitor;
117
118 impl<'de> Visitor<'de> for ItemsVisitor {
119 type Value = Items;
120
121 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
122 formatter.write_str("items")
123 }
124
125 fn visit_seq<V>(self, mut visitor: V) -> Result<Items, V::Error>
126 where
127 V: SeqAccess<'de>,
128 {
129 Ok(Items {
130 matches: handle_unknown(visitor.next_element::<i64>()),
131 wins: handle_unknown(visitor.next_element::<i64>()),
132 item_ids: handle_unknown(visitor.next_element::<Vec<i64>>()),
133 })
134 }
135 }
136
137 deserializer.deserialize_seq(ItemsVisitor)
138 }
139}
140
141#[derive(Debug, Clone, Serialize)]
142pub struct Abilities {
143 pub matches: i64,
144 pub wins: i64,
145 pub ability_order: Vec<char>,
146 pub ability_max_order: String,
147}
148
149impl<'de> Deserialize<'de> for Abilities {
150 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
151 where
152 D: Deserializer<'de>,
153 {
154 struct AbilitiesVisitor;
155
156 impl<'de> Visitor<'de> for AbilitiesVisitor {
157 type Value = Abilities;
158
159 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
160 formatter.write_str("abilities")
161 }
162
163 fn visit_seq<V>(self, mut visitor: V) -> Result<Abilities, V::Error>
164 where
165 V: SeqAccess<'de>,
166 {
167 Ok(Abilities {
168 matches: handle_unknown(visitor.next_element::<i64>()),
169 wins: handle_unknown(visitor.next_element::<i64>()),
170 ability_order: handle_unknown(visitor.next_element::<Vec<char>>()),
171 ability_max_order: handle_unknown(visitor.next_element::<String>()),
172 })
173 }
174 }
175
176 deserializer.deserialize_seq(AbilitiesVisitor)
177 }
178}
179
180#[derive(Debug, Clone, Serialize)]
181pub struct LateItem {
182 pub matches: i64,
183 pub wins: i64,
184 pub id: i64,
185}
186
187impl<'de> Deserialize<'de> for LateItem {
188 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
189 where
190 D: Deserializer<'de>,
191 {
192 struct LateItemVisitor;
193
194 impl<'de> Visitor<'de> for LateItemVisitor {
195 type Value = LateItem;
196
197 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
198 formatter.write_str("summoner spells")
199 }
200
201 fn visit_seq<V>(self, mut visitor: V) -> Result<LateItem, V::Error>
202 where
203 V: SeqAccess<'de>,
204 {
205 Ok(LateItem {
206 id: handle_unknown(visitor.next_element::<i64>()),
207 wins: handle_unknown(visitor.next_element::<i64>()),
208 matches: handle_unknown(visitor.next_element::<i64>()),
209 })
210 }
211 }
212
213 deserializer.deserialize_seq(LateItemVisitor)
214 }
215}
216
217#[derive(Debug, Clone, Serialize, Default)]
218pub struct Shards {
219 pub matches: i64,
220 pub wins: i64,
221 pub shard_ids: Vec<i64>,
222}
223
224impl<'de> Deserialize<'de> for Shards {
225 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
226 where
227 D: Deserializer<'de>,
228 {
229 struct AbilitiesVisitor;
230
231 impl<'de> Visitor<'de> for AbilitiesVisitor {
232 type Value = Shards;
233
234 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
235 formatter.write_str("shards")
236 }
237
238 fn visit_seq<V>(self, mut visitor: V) -> Result<Shards, V::Error>
239 where
240 V: SeqAccess<'de>,
241 {
242 Ok(Shards {
243 matches: handle_unknown(visitor.next_element::<i64>()),
244 wins: handle_unknown(visitor.next_element::<i64>()),
245 shard_ids: handle_unknown(visitor.next_element::<Vec<String>>())
246 .iter()
247 .map(|x| x.parse::<i64>().unwrap_or_default())
248 .collect::<Vec<i64>>(),
249 })
250 }
251 }
252
253 deserializer.deserialize_seq(AbilitiesVisitor)
254 }
255}
256
257impl<'de> Deserialize<'de> for OverviewData {
258 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
259 where
260 D: Deserializer<'de>,
261 {
262 struct OverviewDataVisitor;
263
264 impl<'de> Visitor<'de> for OverviewDataVisitor {
265 type Value = OverviewData;
266
267 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
268 formatter.write_str("overview data")
269 }
270
271 fn visit_seq<V>(self, mut visitor: V) -> Result<OverviewData, V::Error>
272 where
273 V: SeqAccess<'de>,
274 {
275 let runes = visitor
276 .next_element::<Runes>()?
277 .ok_or(serde::de::Error::custom("Could not parse runes."))?;
278 let summoner_spells = visitor
279 .next_element::<SummonerSpells>()?
280 .ok_or(serde::de::Error::custom("Could not parse summoner spells."))?;
281 let starting_items = visitor
282 .next_element::<Items>()?
283 .ok_or(serde::de::Error::custom("Could not parse starting items."))?;
284 let core_items = visitor
285 .next_element::<Items>()?
286 .ok_or(serde::de::Error::custom("Could not parse core items."))?;
287 let abilities = visitor
288 .next_element::<Abilities>()?
289 .ok_or(serde::de::Error::custom("Could not parse abilities."))?;
290 let late_items = visitor
291 .next_element::<Vec<Vec<LateItem>>>()?
292 .ok_or(serde::de::Error::custom("Could not parse late items."))?;
293 let match_info = visitor
294 .next_element::<Vec<i64>>()
295 .unwrap_or_default()
296 .unwrap_or_default();
297 let low_sample_size = match_info.get(1).is_some_and(|games| *games < 1000);
298
299 let _ = visitor.next_element::<IgnoredAny>().is_ok();
301
302 let shards = visitor
303 .next_element::<Shards>()
304 .unwrap_or_default()
305 .unwrap_or_default();
306
307 while let Some(IgnoredAny) = visitor.next_element()? {}
309
310 let overview_data = OverviewData {
311 runes,
312 summoner_spells,
313 starting_items,
314 core_items,
315 abilities,
316 item_4_options: late_items[0].clone(),
317 item_5_options: late_items[1].clone(),
318 item_6_options: late_items[2].clone(),
319 wins: match_info[0],
320 matches: match_info[1],
321 low_sample_size,
322 shards,
323 };
324 Ok(overview_data)
325 }
326 }
327
328 deserializer.deserialize_seq(OverviewDataVisitor)
329 }
330}