Skip to main content

rustigram_api/methods/
games.rs

1use crate::client::BotClient;
2use crate::error::Result;
3use rustigram_types::games::GameHighScore;
4use serde::Serialize;
5use std::future::{Future, IntoFuture};
6use std::pin::Pin;
7
8// ─── Helper macro ─────────────────────────────────────────────────────────────
9
10macro_rules! impl_into_future {
11    ($builder:ident, $return_ty:ty, $method:literal) => {
12        impl IntoFuture for $builder {
13            type Output = Result<$return_ty>;
14            type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
15            fn into_future(self) -> Self::IntoFuture {
16                Box::pin(async move { self.client.post_json($method, &self.params).await })
17            }
18        }
19    };
20}
21
22// ─── setGameScore ─────────────────────────────────────────────────────────────
23
24#[derive(Serialize)]
25struct SetGameScoreParams {
26    user_id: i64,
27    score: u32,
28    #[serde(skip_serializing_if = "Option::is_none")]
29    force: Option<bool>,
30    #[serde(skip_serializing_if = "Option::is_none")]
31    disable_edit_message: Option<bool>,
32    #[serde(skip_serializing_if = "Option::is_none")]
33    chat_id: Option<i64>,
34    #[serde(skip_serializing_if = "Option::is_none")]
35    message_id: Option<i64>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    inline_message_id: Option<String>,
38}
39
40/// Builder for the [`setGameScore`](https://core.telegram.org/bots/api#setgamescore) method.
41///
42/// Sets the score for a user in a game. Returns the edited `Message` on success
43/// for chat messages, or `true` for inline messages.
44///
45/// Returns an error if the new score is not greater than the user's current score
46/// and `force` is not set.
47pub struct SetGameScore {
48    client: BotClient,
49    params: SetGameScoreParams,
50}
51
52impl SetGameScore {
53    pub(crate) fn new(client: BotClient, user_id: i64, score: u32) -> Self {
54        Self {
55            client,
56            params: SetGameScoreParams {
57                user_id,
58                score,
59                force: None,
60                disable_edit_message: None,
61                chat_id: None,
62                message_id: None,
63                inline_message_id: None,
64            },
65        }
66    }
67    /// Pass `true` to allow the score to decrease — useful for fixing mistakes or banning cheaters.
68    pub fn force(mut self, v: bool) -> Self {
69        self.params.force = Some(v);
70        self
71    }
72    /// Pass `true` to prevent the game message from being edited with the new scoreboard.
73    pub fn disable_edit_message(mut self, v: bool) -> Self {
74        self.params.disable_edit_message = Some(v);
75        self
76    }
77    /// Sets the target chat message. Required if `inline_message_id` is not set.
78    pub fn chat_message(mut self, chat_id: i64, message_id: i64) -> Self {
79        self.params.chat_id = Some(chat_id);
80        self.params.message_id = Some(message_id);
81        self
82    }
83    /// Sets the target inline message. Required if `chat_id` and `message_id` are not set.
84    pub fn inline_message_id(mut self, id: impl Into<String>) -> Self {
85        self.params.inline_message_id = Some(id.into());
86        self
87    }
88}
89
90// Returns the edited `Message` as `serde_json::Value` to handle the union
91// return type (`Message | true`) until a proper enum is defined.
92impl_into_future!(SetGameScore, serde_json::Value, "setGameScore");
93
94// ─── getGameHighScores ────────────────────────────────────────────────────────
95
96#[derive(Serialize)]
97struct GetGameHighScoresParams {
98    user_id: i64,
99    #[serde(skip_serializing_if = "Option::is_none")]
100    chat_id: Option<i64>,
101    #[serde(skip_serializing_if = "Option::is_none")]
102    message_id: Option<i64>,
103    #[serde(skip_serializing_if = "Option::is_none")]
104    inline_message_id: Option<String>,
105}
106
107/// Builder for the [`getGameHighScores`](https://core.telegram.org/bots/api#getgamehighscores) method.
108///
109/// Returns the score of the specified user and several of their neighbours
110/// in the game's high score table. Also returns the top 3 users if they are
111/// not among those neighbours.
112pub struct GetGameHighScores {
113    client: BotClient,
114    params: GetGameHighScoresParams,
115}
116
117impl GetGameHighScores {
118    pub(crate) fn new(client: BotClient, user_id: i64) -> Self {
119        Self {
120            client,
121            params: GetGameHighScoresParams {
122                user_id,
123                chat_id: None,
124                message_id: None,
125                inline_message_id: None,
126            },
127        }
128    }
129    /// Sets the target chat message. Required if `inline_message_id` is not set.
130    pub fn chat_message(mut self, chat_id: i64, message_id: i64) -> Self {
131        self.params.chat_id = Some(chat_id);
132        self.params.message_id = Some(message_id);
133        self
134    }
135    /// Sets the target inline message. Required if `chat_id` and `message_id` are not set.
136    pub fn inline_message_id(mut self, id: impl Into<String>) -> Self {
137        self.params.inline_message_id = Some(id.into());
138        self
139    }
140}
141
142impl_into_future!(GetGameHighScores, Vec<GameHighScore>, "getGameHighScores");