arnak/endpoints/
hot_list_models.rs1use core::fmt;
2
3use serde::Deserialize;
4
5use crate::deserialize::{XmlSignedValue, XmlStringValue};
6
7#[derive(Clone, Debug, Deserialize, PartialEq)]
9pub(crate) struct HotList {
10 #[serde(default, rename = "item")]
12 pub(crate) games: Vec<HotListGame>,
13}
14
15#[derive(Clone, Debug, PartialEq)]
19pub struct HotListGame {
20 pub id: u64,
22 pub rank: u64,
24 pub thumbnail: Option<String>,
26 pub name: String,
28 pub year_published: i64,
30}
31
32impl<'de> Deserialize<'de> for HotListGame {
33 fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
34 #[derive(Deserialize)]
35 #[serde(field_identifier, rename_all = "lowercase")]
36 enum Field {
37 ID,
38 Rank,
39 Thumbnail,
40 Name,
41 YearPublished,
42 }
43
44 struct HotListGameVisitor;
45
46 impl<'de> serde::de::Visitor<'de> for HotListGameVisitor {
47 type Value = HotListGame;
48
49 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
50 formatter.write_str("a string containing the XML a game off the hot list.")
51 }
52
53 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
54 where
55 A: serde::de::MapAccess<'de>,
56 {
57 let mut id = None;
58 let mut rank = None;
59 let mut thumbnail = None;
60 let mut name = None;
61 let mut year_published = None;
62 while let Some(key) = map.next_key()? {
63 match key {
64 Field::ID => {
65 if id.is_some() {
66 return Err(serde::de::Error::duplicate_field("id"));
67 }
68 let id_str: String = map.next_value()?;
69 id = Some(id_str.parse::<u64>().map_err(|e| {
70 serde::de::Error::custom(format!(
71 "failed to parse value a u64: {e}"
72 ))
73 })?);
74 },
75 Field::Rank => {
76 if rank.is_some() {
77 return Err(serde::de::Error::duplicate_field("rank"));
78 }
79 let rank_str: String = map.next_value()?;
80 rank = Some(rank_str.parse::<u64>().map_err(|e| {
81 serde::de::Error::custom(format!(
82 "failed to parse value a u64: {e}"
83 ))
84 })?);
85 },
86 Field::Thumbnail => {
87 if thumbnail.is_some() {
88 return Err(serde::de::Error::duplicate_field("thumbnail"));
89 }
90 let thumbnail_xml_tag: XmlStringValue = map.next_value()?;
91 thumbnail = Some(thumbnail_xml_tag.value);
92 },
93 Field::Name => {
94 if name.is_some() {
95 return Err(serde::de::Error::duplicate_field("name"));
96 }
97 let name_xml_tag: XmlStringValue = map.next_value()?;
98 name = Some(name_xml_tag.value);
99 },
100 Field::YearPublished => {
101 if year_published.is_some() {
102 return Err(serde::de::Error::duplicate_field("yearpublished"));
103 }
104 let year_published_xml_tag: XmlSignedValue = map.next_value()?;
105 year_published = Some(year_published_xml_tag.value);
106 },
107 }
108 }
109 let id = id.ok_or_else(|| serde::de::Error::missing_field("id"))?;
110 let rank = rank.ok_or_else(|| serde::de::Error::missing_field("rank"))?;
111 let name = name.ok_or_else(|| serde::de::Error::missing_field("name"))?;
112 let year_published = year_published
113 .ok_or_else(|| serde::de::Error::missing_field("yearpublished"))?;
114 Ok(Self::Value {
115 id,
116 rank,
117 thumbnail,
118 name,
119 year_published,
120 })
121 }
122 }
123 deserializer.deserialize_any(HotListGameVisitor)
124 }
125}