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}