essences/
ratings.rs

1use crate::{characters, mail::MailTemplateId, prelude::*};
2use strum_macros::{Display, EnumIter, EnumString};
3
4#[declare]
5pub type RatingId = Uuid;
6
7#[derive(
8    Clone,
9    Debug,
10    Serialize,
11    Deserialize,
12    JsonSchema,
13    EnumString,
14    Display,
15    PartialEq,
16    Eq,
17    EnumIter,
18    Tsify,
19    Hash,
20)]
21pub enum RatingType {
22    Arena,
23    Power,
24    PvE,
25}
26
27#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, JsonSchema, Tsify)]
28pub struct RatingRangeReward {
29    #[schemars(
30        title = "Id шаблона письма с наградой",
31        schema_with = "option_mail_id_schema"
32    )]
33    pub mail_template_id: Option<MailTemplateId>,
34
35    #[schemars(title = "Место, с которого начинается диапазон")]
36    pub diapason_start: i64,
37
38    #[schemars(
39        title = "Место, на котором заканчивается диапазон. Если отсутствует - значит от старта до конца"
40    )]
41    pub diapason_end: Option<i64>,
42}
43
44#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, JsonSchema, Tsify)]
45pub struct RatingSettings {
46    #[schemars(schema_with = "id_schema")]
47    pub id: RatingId,
48
49    #[schemars(title = "Вид рейтинга")]
50    pub rating_type: RatingType,
51
52    #[schemars(
53        title = "Все места рейтинга c наградой",
54        description = "Набор позиций рейтинга, описывающий все места и награды"
55    )]
56    pub rating_range_rewards: Vec<RatingRangeReward>,
57}
58
59// TODO move to game config impl somewhere
60pub fn get_rating_ranges_by_type(
61    rating_type: RatingType,
62    ratings_settings: &Vec<RatingSettings>,
63) -> Vec<RatingRangeReward> {
64    for settings in ratings_settings {
65        if rating_type == settings.rating_type {
66            return settings.rating_range_rewards.clone();
67        }
68    }
69    vec![]
70}
71
72#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, Eq, PartialEq, JsonSchema, Tsify)]
73#[tsify(into_wasm_abi, from_wasm_abi)]
74pub struct RatingLeaderboardRequest {
75    pub character_id: uuid::Uuid,
76    pub rating_type: RatingType,
77    pub limit: i64,
78    pub offset: i64,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, JsonSchema, Tsify)]
82#[tsify(into_wasm_abi, from_wasm_abi)]
83pub enum RatingLeaderboardResponse {
84    Ok {
85        leaderboard: Vec<RatingRankingItem>,
86        character_ranking: Box<RatingRankingItem>,
87        /// When the current ratings season ends: the next ISO-week start
88        /// (Monday 00:00:00 UTC) strictly after the moment the response was
89        /// built. Matches the weekly ratings rewards cron, which rolls over
90        /// on the ISO-week boundary.
91        season_end: chrono::DateTime<chrono::Utc>,
92    },
93    Error {
94        code: String,
95        message: String,
96        /// See `Ok::season_end`; carried on both variants so the client can
97        /// always read it from the response.
98        season_end: chrono::DateTime<chrono::Utc>,
99    },
100}
101
102#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema, Tsify)]
103pub struct RatingRankingItem {
104    pub user: crate::users::User,
105    pub character: characters::Character,
106    pub place: u64,
107}