1use crate::prelude::{encode, slugify2};
2use crate::scheme::{deserialize_datetime_timestamp, serialize_datetime_timestamp, DDNET_BASE_URL};
3use chrono::{NaiveDate, NaiveDateTime};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub struct Player {
9 pub player: String,
10 pub points: Points,
11 pub team_rank: Option<Rank>,
12 pub rank: Option<Rank>,
13 pub points_last_year: Option<Rank>,
14 pub points_last_month: Option<Rank>,
15 pub points_last_week: Option<Rank>,
16 pub favorite_server: FavoriteServer,
17 pub first_finish: FirstFinish,
18 pub last_finishes: Vec<LastFinish>,
19 #[serde(default)]
20 pub favorite_partners: Vec<FavoritePartner>,
21 pub types: Types,
22 pub activity: Vec<Activity>,
23 pub hours_played_past_365_days: i64,
24}
25
26impl Player {
27 #[must_use]
28 pub fn url(&self) -> String {
29 format!(
30 "https://{}/players/{}",
31 DDNET_BASE_URL,
32 encode(&slugify2(&self.player))
33 )
34 }
35
36 #[must_use]
37 pub fn url_with_name(player: &str) -> String {
38 format!(
39 "https://{}/players/{}",
40 DDNET_BASE_URL,
41 encode(&slugify2(player))
42 )
43 }
44
45 #[must_use]
46 pub fn api(player: &str) -> String {
47 format!(
48 "https://{}/players/?json2={}",
49 DDNET_BASE_URL,
50 encode(player)
51 )
52 }
53}
54
55#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
56pub struct Points {
57 pub total: u64,
58 pub points: Option<u64>,
59 pub rank: Option<u64>,
60}
61
62#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
63pub struct Rank {
64 pub points: Option<u64>,
65 pub rank: Option<u64>,
66}
67
68#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
69pub struct FavoriteServer {
70 pub server: String,
71}
72
73#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
74pub struct FirstFinish {
75 #[serde(
76 serialize_with = "serialize_datetime_timestamp",
77 deserialize_with = "deserialize_datetime_timestamp"
78 )]
79 pub timestamp: NaiveDateTime,
80 pub map: String,
81 pub time: f64,
82}
83
84#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
85pub struct LastFinish {
86 #[serde(
87 serialize_with = "serialize_datetime_timestamp",
88 deserialize_with = "deserialize_datetime_timestamp"
89 )]
90 pub timestamp: NaiveDateTime,
91 pub map: String,
92 pub time: f64,
93 pub country: String,
94 #[serde(rename = "type")]
95 pub type_map: Option<String>,
96}
97
98#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
99pub struct FavoritePartner {
100 pub name: String,
101 pub finishes: i64,
102}
103
104#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
105#[serde(rename_all = "PascalCase")]
106pub struct Types {
107 pub novice: Type,
108 pub moderate: Type,
109 pub brutal: Type,
110 pub insane: Type,
111 pub dummy: Type,
112 #[serde(rename = "DDmaX.Easy")]
113 pub ddmax_easy: Type,
114 #[serde(rename = "DDmaX.Next")]
115 pub ddmax_next: Type,
116 #[serde(rename = "DDmaX.Pro")]
117 pub ddmax_pro: Type,
118 #[serde(rename = "DDmaX.Nut")]
119 pub ddmax_nut: Type,
120 pub oldschool: Type,
121 pub solo: Type,
122 pub race: Type,
123 pub fun: Type,
124 pub event: Type,
125}
126
127#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
128pub struct Type {
129 pub points: Points,
130 pub team_rank: Option<Rank>,
131 pub rank: Option<Rank>,
132 pub maps: HashMap<String, DDMap>,
133}
134
135#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
136pub struct DDMap {
137 pub points: i64,
138 pub total_finishes: i64,
139 pub finishes: i64,
140 pub team_rank: Option<i64>,
141 pub rank: Option<i64>,
142 pub time: Option<f64>,
143 pub first_finish: Option<f64>,
144}
145
146#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
147pub struct Activity {
148 pub date: NaiveDate,
149 pub hours_played: i64,
150}