1use super::RequestParameters;
7#[cfg(feature = "raw")]
8use super::{Player, Response, ServerInfo};
9use reqwest::Error;
10use serde::Deserialize;
11#[cfg(feature = "raw")]
12use serde::Serialize;
13
14#[cfg_attr(feature = "raw", derive(Serialize, Clone))]
16#[derive(Deserialize)]
17pub struct RawResponse {
18 #[allow(missing_docs)]
19 #[serde(rename = "Success")]
20 pub success: bool,
21 #[allow(missing_docs)]
22 #[serde(rename = "Error", skip_serializing_if = "Option::is_none", default)]
23 pub error: Option<String>,
24 #[allow(missing_docs)]
25 #[serde(rename = "Servers", skip_serializing_if = "Option::is_none", default)]
26 pub servers: Option<Vec<RawServerInfo>>,
27 #[allow(missing_docs)]
28 #[serde(rename = "Success", skip_serializing_if = "Option::is_none", default)]
29 pub cooldown: Option<u64>,
30}
31
32#[cfg(feature = "raw")]
33impl From<Response> for RawResponse {
34 fn from(response: Response) -> Self {
35 match response {
36 Response::Success(success) => RawResponse {
37 success: true,
38 error: None,
39 servers: Some(
40 success
41 .servers
42 .into_iter()
43 .map(RawServerInfo::from)
44 .collect(),
45 ),
46 cooldown: Some(success.cooldown),
47 },
48 Response::Error(error) => RawResponse {
49 success: false,
50 error: Some(error.error),
51 servers: None,
52 cooldown: None,
53 },
54 }
55 }
56}
57
58#[cfg_attr(feature = "raw", derive(Serialize, Clone))]
60#[derive(Deserialize)]
61pub struct RawServerInfo {
62 #[allow(missing_docs)]
63 #[serde(rename = "ID")]
64 pub id: u64,
65 #[allow(missing_docs)]
66 #[serde(rename = "Port")]
67 pub port: u16,
68 #[allow(missing_docs)]
69 #[serde(
70 rename = "LastOnline",
71 skip_serializing_if = "Option::is_none",
72 default
73 )]
74 pub last_online: Option<String>,
75 #[allow(missing_docs)]
76 #[serde(rename = "Players", skip_serializing_if = "Option::is_none", default)]
77 pub players_count: Option<String>,
78 #[allow(missing_docs)]
79 #[serde(
80 rename = "PlayersList",
81 skip_serializing_if = "Option::is_none",
82 default
83 )]
84 pub players: Option<Vec<RawPlayer>>,
85 #[allow(missing_docs)]
86 #[serde(rename = "Info", skip_serializing_if = "Option::is_none", default)]
87 pub info: Option<String>,
88 #[allow(missing_docs)]
89 #[serde(rename = "FF", skip_serializing_if = "Option::is_none", default)]
90 pub friendly_fire: Option<bool>,
91 #[allow(missing_docs)]
92 #[serde(rename = "WL", skip_serializing_if = "Option::is_none", default)]
93 pub whitelist: Option<bool>,
94 #[allow(missing_docs)]
95 #[serde(rename = "Modded", skip_serializing_if = "Option::is_none", default)]
96 pub modded: Option<bool>,
97 #[allow(missing_docs)]
98 #[serde(rename = "Mods", skip_serializing_if = "Option::is_none", default)]
99 pub mods: Option<u64>,
100 #[allow(missing_docs)]
101 #[serde(rename = "Suppress", skip_serializing_if = "Option::is_none", default)]
102 pub suppress: Option<bool>,
103 #[allow(missing_docs)]
104 #[serde(
105 rename = "AutoSuppress",
106 skip_serializing_if = "Option::is_none",
107 default
108 )]
109 pub auto_suppress: Option<bool>,
110}
111
112#[cfg(feature = "raw")]
113impl From<ServerInfo> for RawServerInfo {
114 fn from(server_info: ServerInfo) -> Self {
115 Self {
116 id: server_info.id,
117 port: server_info.port,
118 last_online: server_info
119 .last_online
120 .map(|date| date.format("%Y-%m-%d").to_string()),
121 players_count: server_info.players_count.map(|players_count| {
122 format!(
123 "{}/{}",
124 players_count.current_players, players_count.max_players
125 )
126 }),
127 players: server_info
128 .players
129 .map(|players| players.into_iter().map(RawPlayer::from).collect()),
130 info: server_info.info.map(base64::encode),
131 friendly_fire: server_info.friendly_fire,
132 whitelist: server_info.whitelist,
133 modded: server_info.modded,
134 mods: server_info.mods,
135 suppress: server_info.suppress,
136 auto_suppress: server_info.auto_suppress,
137 }
138 }
139}
140
141#[cfg_attr(feature = "raw", derive(Serialize, Clone))]
143#[derive(Deserialize)]
144#[serde(untagged)]
145pub enum RawPlayer {
146 UserId(String),
148 UserIdWithNickname {
150 #[serde(rename = "ID")]
152 id: String,
153 #[serde(rename = "Nickname", default)]
155 nickname: Option<String>,
156 },
157}
158
159#[cfg(feature = "raw")]
160impl From<Player> for RawPlayer {
161 fn from(player: Player) -> Self {
162 if let Some(nickname) = player.nickname {
163 Self::UserIdWithNickname {
164 id: player.id,
165 nickname: Some(nickname),
166 }
167 } else {
168 Self::UserId(player.id)
169 }
170 }
171}
172
173pub async fn get<'a>(parameters: &'a RequestParameters) -> Result<RawResponse, Error> {
177 let mut url = parameters.url.to_owned();
178
179 {
180 let mut query_parameters = url.query_pairs_mut();
181
182 if let Some(id) = parameters.id {
183 query_parameters.append_pair("id", id.to_string().as_str());
184 }
185 if let Some(key) = ¶meters.key {
186 query_parameters.append_pair("key", key.as_str());
187 }
188 if parameters.last_online {
189 query_parameters.append_pair("lo", "true");
190 }
191 if parameters.players {
192 query_parameters.append_pair("players", "true");
193 }
194 if parameters.list {
195 query_parameters.append_pair("list", "true");
196 }
197 if parameters.info {
198 query_parameters.append_pair("info", "true");
199 }
200 if parameters.pastebin {
201 query_parameters.append_pair("pastebin", "true");
202 }
203 if parameters.version {
204 query_parameters.append_pair("version", "true");
205 }
206 if parameters.flags {
207 query_parameters.append_pair("flags", "true");
208 }
209 if parameters.nicknames {
210 query_parameters.append_pair("nicknames", "true");
211 }
212 if parameters.online {
213 query_parameters.append_pair("online", "true");
214 }
215 }
216
217 Ok(reqwest::get(url).await?.json().await?)
218}