tg_flows/types/
poll.rs

1use crate::types::{MessageEntity, PollType, User};
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6/// This object contains information about a poll.
7///
8/// [The official docs](https://core.telegram.org/bots/api#poll).
9#[serde_with_macros::skip_serializing_none]
10#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
11pub struct Poll {
12    /// Unique poll identifier.
13    pub id: String,
14
15    /// Poll question, 1-255 characters.
16    pub question: String,
17
18    /// List of poll options.
19    pub options: Vec<PollOption>,
20
21    /// `true`, if the poll is closed.
22    pub is_closed: bool,
23
24    /// Total number of users that voted in the poll
25    pub total_voter_count: i32,
26
27    /// True, if the poll is anonymous
28    pub is_anonymous: bool,
29
30    /// Poll type, currently can be “regular” or “quiz”
31    #[serde(rename = "type")]
32    pub poll_type: PollType,
33
34    /// True, if the poll allows multiple answers
35    pub allows_multiple_answers: bool,
36
37    /// 0-based identifier of the correct answer option. Available only for
38    /// polls in the quiz mode, which are closed, or was sent (not
39    /// forwarded) by the bot or to the private chat with the bot.
40    pub correct_option_id: Option<u8>,
41
42    /// Text that is shown when a user chooses an incorrect answer or taps on
43    /// the lamp icon in a quiz-style poll, 0-200 characters.
44    pub explanation: Option<String>,
45
46    /// Special entities like usernames, URLs, bot commands, etc. that appear in
47    /// the explanation.
48    pub explanation_entities: Option<Vec<MessageEntity>>,
49
50    /// Amount of time in seconds the poll will be active after creation.
51    pub open_period: Option<u16>,
52
53    /// Point in time when the poll will be automatically closed.
54    #[serde(default, with = "crate::types::serde_opt_date_from_unix_timestamp")]
55    pub close_date: Option<DateTime<Utc>>,
56}
57
58/// This object contains information about one answer option in a poll.
59///
60/// [The official docs](https://core.telegram.org/bots/api#polloption).
61#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
62pub struct PollOption {
63    /// Option text, 1-100 characters.
64    pub text: String,
65
66    /// Number of users that voted for this option.
67    pub voter_count: i32,
68}
69
70impl Poll {
71    /// Returns all users that are "contained" in this `Poll`
72    /// structure.
73    ///
74    /// This might be useful to track information about users.
75    ///
76    /// Note that this function can return duplicate users.
77    pub fn mentioned_users(&self) -> impl Iterator<Item = &User> {
78        use crate::util::{flatten, mentioned_users_from_entities};
79
80        flatten(self.explanation_entities.as_deref().map(mentioned_users_from_entities))
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn deserialize() {
90        let data = r#"
91        {
92            "allows_multiple_answers": false,
93            "id": "5377643193141559299",
94            "is_anonymous": true,
95            "is_closed": false,
96            "options": [
97                {
98                    "text": "1",
99                    "voter_count": 1
100                },
101                {
102                    "text": "2",
103                    "voter_count": 0
104                },
105                {
106                    "text": "3",
107                    "voter_count": 0
108                },
109                {
110                    "text": "4",
111                    "voter_count": 0
112                },
113                {
114                    "text": "5",
115                    "voter_count": 0
116                }
117            ],
118            "question": "Rate me from 1 to 5.",
119            "total_voter_count": 1,
120            "type": "regular"
121        }
122        "#;
123        serde_json::from_str::<Poll>(data).unwrap();
124    }
125}